2 ** COWLOOP block device driver (2.6 kernel compliant)
3 ** =======================================================================
4 ** Read-write loop-driver with copy-on-write functionality.
8 ** modprobe cowloop [maxcows=..] [rdofile=..... cowfile=.... [option=r]]
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)
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
20 ** Other cowdevices can be activated via the command "cowdev"
21 ** whenever the cowloop-driver is loaded.
23 ** The read-only file may be of type 'regular' or 'block-device'.
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
34 ** +-----------------------------+
35 ** | cow head block | MAPUNIT bytes
36 ** |-----------------------------|
41 ** | used-block bitmap | MAPUNIT bytes
42 ** |-----------------------------|
43 ** | gap to align start-offset |
45 ** |-----------------------------| <---- start-offset cow blocks
47 ** | written cow blocks | MAPUNIT bytes
51 ** - contains general info about the rdofile which is related
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
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
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
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.
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 ** ----------------------------------------------------------------------------
82 ** Major modifications:
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
96 ** loop.c by Theodore Ts'o and
97 ** cloop.c by Paul `Rusty' Russell & Klaus Knopper.
99 ** Design-considerations:
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).
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%.
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 */
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 $
133 ** Revision 1.30 2009/02/08 hjt
134 ** Integrated earlier fixes
135 ** Upgraded to kernel 2.6.28 (thanks Jerome Poulin)
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
142 ** Revision 1.28 2006/08/16 16:00:00 hjt
143 ** malloc each individual cowloopdevice struct separately
145 ** Revision 1.27 2006/03/14 14:57:03 root
146 ** Removed include version.h
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.
151 ** Revision 1.25 2005/08/03 14:00:39 root
152 ** Added modinfo info to driver.
154 ** Revision 1.24 2005/07/21 06:14:53 root
155 ** Cosmetic changes source code.
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.
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.
165 ** Revision 1.21 2005/07/19 09:21:52 root
166 ** Removing maximum limit of 16 Gb per cowdevice.
168 ** Revision 1.20 2005/07/19 07:50:33 root
169 ** Minor bugfixes and cosmetic changes.
171 ** Revision 1.19 2005/06/10 12:29:55 root
172 ** Removed lock/unlock operation from cowlo_open().
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).
178 ** Revision 1.17 2005/03/17 14:36:16 root
179 ** Fixed some license issues.
181 ** Revision 1.16 2005/03/07 14:42:05 root
182 ** Only allow one parallel open per cowdevice.
184 ** Revision 1.15 2005/02/18 11:52:04 gerlof
185 ** Redesign to support more than one cowdevice > 2 Gb space.
187 ** Revision 1.14 2004/08/17 14:19:16 gerlof
188 ** Modified output of /proc/cowloop.
190 ** Revision 1.13 2004/08/16 07:21:10 gerlof
191 ** Separate statistical counter for read on rdofile and cowfile.
193 ** Revision 1.12 2004/08/11 06:52:11 gerlof
194 ** Modified messages.
196 ** Revision 1.11 2004/08/11 06:44:11 gerlof
197 ** Modified log messages.
199 ** Revision 1.10 2004/08/10 12:27:27 gerlof
202 ** Revision 1.9 2004/08/09 11:43:37 gerlof
203 ** Removed double definition of major number (COWMAJOR).
205 ** Revision 1.8 2004/08/09 08:03:39 gerlof
206 ** Cleanup of messages.
208 ** Revision 1.7 2004/05/27 06:37:33 gerlof
209 ** Modified /proc message.
211 ** Revision 1.6 2004/05/26 21:23:28 gerlof
212 ** Modified /proc output.
214 ** Revision 1.5 2004/05/26 13:23:34 gerlof
215 ** Support cowsync to force flushing the bitmaps and cowhead.
217 ** Revision 1.4 2004/05/26 11:11:10 gerlof
218 ** Updated the comment to the actual situation.
220 ** Revision 1.3 2004/05/26 10:50:00 gerlof
221 ** Implemented recovery-option.
223 ** Revision 1.2 2004/05/25 15:14:41 gerlof
224 ** Modified bitmap flushing strategy.
233 #define DEBUGP printk
234 #define DCOW KERN_ALERT
236 #define DEBUGP(format, x...)
239 #include <linux/types.h>
240 #include <linux/autoconf.h>
241 #ifndef AUTOCONF_INCLUDED
242 #include <linux/config.h>
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 #include <linux/semaphore.h>
258 #include <asm/uaccess.h>
259 #include <linux/proc_fs.h>
260 #include <linux/blkdev.h>
261 #include <linux/buffer_head.h>
262 #include <linux/hdreg.h>
263 #include <linux/genhd.h>
264 #include <linux/statfs.h>
268 MODULE_LICENSE("GPL");
269 /* MODULE_AUTHOR("Gerlof Langeveld <gerlof@ATComputing.nl>"); obsolete address */
270 MODULE_AUTHOR("Hendrik-Jan Thomassen <hjt@ATComputing.nl>"); /* current maintainer */
271 MODULE_DESCRIPTION("Copy-on-write loop driver");
272 MODULE_PARM_DESC(maxcows
, " Number of configured cowdevices (default 16)");
273 MODULE_PARM_DESC(rdofile
, " Read-only file for /dev/cow/0");
274 MODULE_PARM_DESC(cowfile
, " Cowfile for /dev/cow/0");
275 MODULE_PARM_DESC(option
, " Repair cowfile if inconsistent: option=r");
277 #define DEVICE_NAME "cow"
279 #define DFLCOWS 16 /* default cowloop devices */
281 static int maxcows
= DFLCOWS
;
282 module_param(maxcows
, int, 0);
283 static char *rdofile
= "";
284 module_param(rdofile
, charp
, 0);
285 static char *cowfile
= "";
286 module_param(cowfile
, charp
, 0);
287 static char *option
= "";
288 module_param(option
, charp
, 0);
291 ** per cowdevice several bitmap chunks are allowed of MAPCHUNKSZ each
293 ** each bitmap chunk can describe MAPCHUNKSZ * 8 * MAPUNIT bytes of data
295 ** MAPCHUNKSZ 4096 and MAPUNIT 1024 --> 4096 * 8 * 1024 = 32 Mb per chunk
297 #define MAPCHUNKSZ 4096 /* #bytes per bitmap chunk (do not change) */
299 #define SPCMINBLK 100 /* space threshold to give warning messages */
300 #define SPCDFLINTVL 16 /* once every SPCDFLINTVL writes to cowfile, */
301 /* available space in filesystem is checked */
303 #define CALCMAP(x) ((x)/(MAPCHUNKSZ*8))
304 #define CALCBYTE(x) (((x)%(MAPCHUNKSZ*8))>>3)
305 #define CALCBIT(x) ((x)&7)
311 static char allzeroes
[MAPUNIT
];
314 ** administration per cowdevice (pair of cowfile/rdofile)
317 /* bit-values for state */
318 #define COWDEVOPEN 0x01 /* cowdevice opened */
319 #define COWRWCOWOPEN 0x02 /* cowfile opened read-write */
320 #define COWRDCOWOPEN 0x04 /* cowfile opened read-only */
321 #define COWWATCHDOG 0x08 /* ioctl for watchdog cowfile space active */
323 #define COWCOWOPEN (COWRWCOWOPEN|COWRDCOWOPEN)
325 struct cowloop_device
330 int state
; /* bit-values (see above) */
331 int opencnt
; /* # opens for cowdevice */
334 ** open file pointers
336 struct file
*rdofp
, *cowfp
; /* open file pointers */
337 char *rdoname
, *cowname
; /* file names */
340 ** request queue administration
342 struct request_queue
*rqueue
;
347 ** administration about read-only file
349 unsigned int numblocks
; /* # blocks input file in MAPUNIT */
350 unsigned int blocksz
; /* minimum unit to access this dev */
351 unsigned long fingerprint
; /* fingerprint of current rdofile */
352 struct block_device
*belowdev
; /* block device below us */
353 struct gendisk
*belowgd
; /* gendisk for blk dev below us */
354 struct request_queue
*belowq
; /* req. queue of blk dev below us */
357 ** bitmap administration to register which blocks are modified
359 long int mapsize
; /* total size of bitmap (bytes) */
360 long int mapremain
; /* remaining bytes in last bitmap */
361 int mapcount
; /* number of bitmaps in use */
362 char **mapcache
; /* area with pointers to bitmaps */
364 char *iobuf
; /* databuffer of MAPUNIT bytes */
365 struct cowhead
*cowhead
; /* buffer containing cowhead */
368 ** administration for interface with the kernel-thread
370 int pid
; /* pid==0: no thread available */
371 struct request
*req
; /* request to be handled now */
372 wait_queue_head_t waitq
; /* wait-Q: thread waits for work */
373 char closedown
; /* boolean: thread exit required */
374 char qfilled
; /* boolean: I/O request pending */
375 char iobusy
; /* boolean: req under treatment */
378 ** administration to keep track of free space in cowfile filesystem
380 unsigned long blksize
; /* block size of fs (bytes) */
381 unsigned long blktotal
; /* recent total space in fs (blocks) */
382 unsigned long blkavail
; /* recent free space in fs (blocks) */
384 wait_queue_head_t watchq
; /* wait-Q: watcher awaits threshold */
385 unsigned long watchthresh
; /* threshold of watcher (blocks) */
388 ** statistical counters
390 unsigned long rdoreads
; /* number of read-actions rdo */
391 unsigned long cowreads
; /* number of read-actions cow */
392 unsigned long cowwrites
; /* number of write-actions */
393 unsigned long nrcowblocks
; /* number of blocks in use on cow */
396 static struct cowloop_device
**cowdevall
; /* ptr to ptrs to all cowdevices */
397 static struct semaphore cowdevlock
; /* generic lock for cowdevs */
399 static struct gendisk
*cowctlgd
; /* gendisk control channel */
400 static spinlock_t cowctlrqlock
; /* for req.q. of ctrl. channel */
403 ** private directory /proc/cow
405 struct proc_dir_entry
*cowlo_procdir
;
408 ** function prototypes
410 static long int cowlo_do_request (struct request
*req
);
411 static void cowlo_sync (void);
412 static int cowlo_checkio (struct cowloop_device
*, int, loff_t
);
413 static int cowlo_readmix (struct cowloop_device
*, void *, int, loff_t
);
414 static int cowlo_writemix (struct cowloop_device
*, void *, int, loff_t
);
415 static long int cowlo_readrdo (struct cowloop_device
*, void *, int, loff_t
);
416 static long int cowlo_readcow (struct cowloop_device
*, void *, int, loff_t
);
417 static long int cowlo_readcowraw (struct cowloop_device
*, void *, int, loff_t
);
418 static long int cowlo_writecow (struct cowloop_device
*, void *, int, loff_t
);
419 static long int cowlo_writecowraw(struct cowloop_device
*, void *, int, loff_t
);
420 static int cowlo_ioctl (struct block_device
*, fmode_t
,
421 unsigned int, unsigned long);
422 static int cowlo_makepair (struct cowpair __user
*);
423 static int cowlo_removepair (unsigned long __user
*);
424 static int cowlo_watch (struct cowpair __user
*);
425 static int cowlo_cowctl (unsigned long __user
*, int);
426 static int cowlo_openpair (char *, char *, int, int);
427 static int cowlo_closepair (struct cowloop_device
*);
428 static int cowlo_openrdo (struct cowloop_device
*, char *);
429 static int cowlo_opencow (struct cowloop_device
*, char *, int);
430 static void cowlo_undo_openrdo(struct cowloop_device
*);
431 static void cowlo_undo_opencow(struct cowloop_device
*);
433 /*****************************************************************************/
434 /* System call handling */
435 /*****************************************************************************/
438 ** handle system call open()/mount()
444 static int cowlo_open(struct block_device
*bdev
, fmode_t mode
)
446 struct inode
*inode
= bdev
->bd_inode
;
451 if (imajor(inode
) != COWMAJOR
) {
453 "cowloop - unexpected major %d\n", imajor(inode
));
457 switch (iminor(inode
)) {
459 DEBUGP(DCOW
"cowloop - open %d control\n", COWCTL
);
463 DEBUGP(DCOW
"cowloop - open minor %d\n", iminor(inode
));
465 if ( iminor(inode
) >= maxcows
)
468 if ( !((cowdevall
[iminor(inode
)])->state
& COWDEVOPEN
) )
471 (cowdevall
[iminor(inode
)])->opencnt
++;
478 ** handle system call close()/umount()
483 static int cowlo_release(struct gendisk
*gd
, fmode_t mode
)
485 struct block_device
*bdev
;
488 bdev
= bdget_disk(gd
, 0);
489 inode
= bdev
->bd_inode
;
493 DEBUGP(DCOW
"cowloop - release (close) minor %d\n", iminor(inode
));
495 if ( iminor(inode
) != COWCTL
)
496 (cowdevall
[iminor(inode
)])->opencnt
--;
502 ** handle system call ioctl()
508 static int cowlo_ioctl(struct block_device
*bdev
, fmode_t mode
,
509 unsigned int cmd
, unsigned long arg
)
511 struct hd_geometry geo
;
512 struct inode
*inode
= bdev
->bd_inode
;
514 DEBUGP(DCOW
"cowloop - ioctl cmd %x\n", cmd
);
516 switch ( iminor(inode
) ) {
519 ** allowed via control device only
524 ** write all bitmap chunks and cowheaders to cowfiles
533 ** open a new cowdevice (pair of rdofile/cowfile)
536 return cowlo_makepair((void __user
*)arg
);
539 ** close a cowdevice (pair of rdofile/cowfile)
542 return cowlo_removepair((void __user
*)arg
);
545 ** watch free space of filesystem containing cowfile
548 return cowlo_watch((void __user
*)arg
);
551 ** close cowfile for active device
554 return cowlo_cowctl((void __user
*)arg
, COWCLOSE
);
557 ** reopen cowfile read-only for active device
560 return cowlo_cowctl((void __user
*)arg
, COWRDOPEN
);
564 } /* end of switch on command */
567 ** allowed for any other cowdevice
572 ** HDIO_GETGEO must be supported for fdisk, etc
579 if (copy_to_user((void __user
*)arg
, &geo
, sizeof geo
))
585 } /* end of switch on ioctl-cmd code parameter */
586 } /* end of switch on minor number */
589 static struct block_device_operations cowlo_fops
=
591 .owner
= THIS_MODULE
,
592 .open
= cowlo_open
, /* called upon open */
593 .release
= cowlo_release
, /* called upon close */
594 .ioctl
= cowlo_ioctl
, /* called upon ioctl */
598 ** handle ioctl-command COWMKPAIR:
599 ** open a new cowdevice (pair of rdofile/cowfile) on-the-fly
606 cowlo_makepair(struct cowpair __user
*arg
)
609 struct cowpair cowpair
;
610 unsigned char *cowpath
;
611 unsigned char *rdopath
;
614 ** retrieve info about pathnames
616 if ( copy_from_user(&cowpair
, arg
, sizeof cowpair
) )
619 if ( (MAJOR(cowpair
.device
) != COWMAJOR
) && (cowpair
.device
!= ANYDEV
) )
622 if ( (MINOR(cowpair
.device
) >= maxcows
) && (cowpair
.device
!= ANYDEV
) )
626 ** retrieve pathname strings
628 if ( (cowpair
.cowflen
> PATH_MAX
) || (cowpair
.rdoflen
> PATH_MAX
) )
629 return -ENAMETOOLONG
;
631 if ( !(cowpath
= kmalloc(cowpair
.cowflen
+1, GFP_KERNEL
)) )
634 if ( copy_from_user(cowpath
, (void __user
*)cowpair
.cowfile
,
639 *(cowpath
+cowpair
.cowflen
) = 0;
641 if ( !(rdopath
= kmalloc(cowpair
.rdoflen
+1, GFP_KERNEL
)) ) {
646 if ( copy_from_user(rdopath
, (void __user
*)cowpair
.rdofile
,
652 *(rdopath
+cowpair
.rdoflen
) = 0;
655 ** open new cowdevice
657 if ( cowpair
.device
== ANYDEV
) {
659 ** search first unused minor
661 for (i
=0, rv
=-EBUSY
; i
< maxcows
; i
++) {
662 if ( !((cowdevall
[i
])->state
& COWDEVOPEN
) ) {
663 rv
= cowlo_openpair(rdopath
, cowpath
, 0, i
);
668 if (rv
) { /* open failed? */
675 ** return newly allocated cowdevice to user space
677 cowpair
.device
= MKDEV(COWMAJOR
, i
);
679 if ( copy_to_user(arg
, &cowpair
, sizeof cowpair
)) {
684 } else { /* specific minor requested */
685 if ( (rv
= cowlo_openpair(rdopath
, cowpath
, 0,
686 MINOR(cowpair
.device
)))) {
697 ** handle ioctl-command COWRMPAIR:
698 ** deactivate an existing cowdevice (pair of rdofile/cowfile) on-the-fly
705 cowlo_removepair(unsigned long __user
*arg
)
707 unsigned long cowdevice
;
708 struct cowloop_device
*cowdev
;
711 ** retrieve info about device to be removed
713 if ( copy_from_user(&cowdevice
, arg
, sizeof cowdevice
))
717 ** verify major-minor number
719 if ( MAJOR(cowdevice
) != COWMAJOR
)
722 if ( MINOR(cowdevice
) >= maxcows
)
725 cowdev
= cowdevall
[MINOR(cowdevice
)];
727 if ( !(cowdev
->state
& COWDEVOPEN
) )
731 ** synchronize bitmaps and close cowdevice
733 if (cowdev
->state
& COWRWCOWOPEN
) {
739 return cowlo_closepair(cowdev
);
743 ** handle ioctl-command COWWATCH:
744 ** watch the free space of the filesystem containing a cowfile
745 ** of an open cowdevice
752 cowlo_watch(struct cowpair __user
*arg
)
754 struct cowloop_device
*cowdev
;
755 struct cowwatch cowwatch
;
758 ** retrieve structure holding info
760 if ( copy_from_user(&cowwatch
, arg
, sizeof cowwatch
))
764 ** verify if cowdevice exists and is currently open
766 if ( MINOR(cowwatch
.device
) >= maxcows
)
769 cowdev
= cowdevall
[MINOR(cowwatch
.device
)];
771 if ( !(cowdev
->state
& COWDEVOPEN
) )
775 ** if the WATCHWAIT-option is set, wait until the indicated
776 ** threshold is reached (only one waiter allowed)
778 if (cowwatch
.flags
& WATCHWAIT
) {
780 ** check if already another waiter active
781 ** for this cowdevice
783 if (cowdev
->state
& COWWATCHDOG
)
786 cowdev
->state
|= COWWATCHDOG
;
788 cowdev
->watchthresh
= (unsigned long long)
790 (cowdev
->blksize
/ 1024);
792 if (wait_event_interruptible(cowdev
->watchq
,
793 cowdev
->watchthresh
>= cowdev
->blkavail
)) {
794 cowdev
->state
&= ~COWWATCHDOG
;
798 cowdev
->state
&= ~COWWATCHDOG
;
801 cowwatch
.totalkb
= (unsigned long long)cowdev
->blktotal
*
802 cowdev
->blksize
/ 1024;
803 cowwatch
.availkb
= (unsigned long long)cowdev
->blkavail
*
804 cowdev
->blksize
/ 1024;
806 if ( copy_to_user(arg
, &cowwatch
, sizeof cowwatch
))
813 ** handle ioctl-commands COWCLOSE and COWRDOPEN:
814 ** COWCLOSE - close the cowfile while the cowdevice remains open;
815 ** this allows an unmount of the filesystem on which
816 ** the cowfile resides
817 ** COWRDOPEN - close the cowfile and reopen it for read-only;
818 ** this allows a remount read-ony of the filesystem
819 ** on which the cowfile resides
826 cowlo_cowctl(unsigned long __user
*arg
, int cmd
)
828 struct cowloop_device
*cowdev
;
829 unsigned long cowdevice
;
832 ** retrieve info about device to be removed
834 if ( copy_from_user(&cowdevice
, arg
, sizeof cowdevice
))
838 ** verify major-minor number
840 if ( MAJOR(cowdevice
) != COWMAJOR
)
843 if ( MINOR(cowdevice
) >= maxcows
)
846 cowdev
= cowdevall
[MINOR(cowdevice
)];
848 if ( !(cowdev
->state
& COWDEVOPEN
) )
852 ** synchronize bitmaps and close cowfile
854 if (cowdev
->state
& COWRWCOWOPEN
) {
861 ** handle specific ioctl-command
866 ** if the cowfile is still opened read-write
868 if (cowdev
->state
& COWRWCOWOPEN
) {
873 filp_close(cowdev
->cowfp
, 0);
875 cowdev
->state
&= ~COWRWCOWOPEN
;
878 ** open again for read-only
880 cowdev
->cowfp
= filp_open(cowdev
->cowname
,
881 O_RDONLY
|O_LARGEFILE
, 0600);
883 if ( (cowdev
->cowfp
== NULL
) || IS_ERR(cowdev
->cowfp
) ) {
885 "cowloop - failed to reopen cowfile %s\n",
891 ** mark cowfile open for read-only
893 cowdev
->state
|= COWRDCOWOPEN
;
901 ** if the cowfile is still open
903 if (cowdev
->state
& COWCOWOPEN
) {
908 filp_close(cowdev
->cowfp
, 0);
910 cowdev
->state
&= ~COWCOWOPEN
;
918 /*****************************************************************************/
919 /* Handling of I/O-requests for a cowdevice */
920 /*****************************************************************************/
923 ** function to be called by core-kernel to handle the I/O-requests
926 static void cowlo_request(struct request_queue
*q
)
929 struct cowloop_device
*cowdev
;
931 DEBUGP(DCOW
"cowloop - request function called....\n");
933 while((req
= blk_peek_request(q
)) != NULL
) {
934 DEBUGP(DCOW
"cowloop - got next request\n");
936 if (! blk_fs_request(req
)) {
937 /* this is not a normal file system request */
938 __blk_end_request_cur(req
, -EIO
);
941 cowdev
= req
->rq_disk
->private_data
;
949 ** when no kernel-thread is available, the request will
950 ** produce an I/O-error
953 printk(KERN_ERR
"cowloop - no thread available\n");
954 __blk_end_request_cur(req
, -EIO
); /* request failed */
960 ** handle I/O-request in the context of the kernel-thread
965 wake_up_interruptible_sync(&cowdev
->waitq
);
968 ** get out of this function now while the I/O-request is
969 ** under treatment of the kernel-thread; this function
970 ** will be called again after the current I/O-request has
971 ** been finished by the thread
978 ** daemon-process (kernel-thread) executes this function
981 cowlo_daemon(struct cowloop_device
*cowdev
)
987 for (minor
= 0; minor
< maxcows
; minor
++) {
988 if (cowdev
== cowdevall
[minor
]) break;
990 sprintf(myname
, "cowloopd%d", minor
);
994 while (!cowdev
->closedown
) {
996 ** sleep while waiting for an I/O request;
997 ** note that no non-interruptible wait has been used
998 ** because the non-interruptible version of
999 ** a *synchronous* wake_up does not exist (any more)
1001 if (wait_event_interruptible(cowdev
->waitq
, cowdev
->qfilled
)){
1002 flush_signals(current
); /* ignore signal-based wakeup */
1006 if (cowdev
->closedown
) /* module will be unloaded ? */{
1012 ** woken up by the I/O-request handler: treat requested I/O
1014 cowdev
->qfilled
= 0;
1016 rv
= cowlo_do_request(cowdev
->req
);
1019 ** reacquire the queue-spinlock for manipulating
1020 ** the request-queue and dequeue the request
1022 spin_lock_irq(&cowdev
->rqlock
);
1024 __blk_end_request_cur(cowdev
->req
, rv
);
1028 ** initiate the next request from the queue
1030 cowlo_request(cowdev
->rqueue
);
1032 spin_unlock_irq(&cowdev
->rqlock
);
1038 ** function to be called in the context of the kernel thread
1039 ** to handle the queued I/O-requests
1046 cowlo_do_request(struct request
*req
)
1051 struct cowloop_device
*cowdev
= req
->rq_disk
->private_data
;
1054 ** calculate some variables which are needed later on
1056 len
= blk_rq_cur_sectors(req
) << 9;
1057 offset
= (loff_t
) blk_rq_pos(req
) << 9;
1059 DEBUGP(DCOW
"cowloop - req cmd=%d offset=%lld len=%lu addr=%p\n",
1060 *(req
->cmd
), offset
, len
, req
->buffer
);
1063 ** handle READ- or WRITE-request
1065 switch (rq_data_dir(req
)) {
1066 /**********************************************************/
1068 switch ( cowlo_checkio(cowdev
, len
, offset
) ) {
1070 rv
= cowlo_readcow(cowdev
, req
->buffer
, len
, offset
);
1074 rv
= cowlo_readrdo(cowdev
, req
->buffer
, len
, offset
);
1078 rv
= cowlo_readmix(cowdev
, req
->buffer
, len
, offset
);
1082 rv
= 0; /* never happens */
1086 /**********************************************************/
1088 switch ( cowlo_checkio(cowdev
, len
, offset
) ) {
1091 ** straight-forward write will do...
1093 DEBUGP(DCOW
"cowloop - write straight ");
1095 rv
= cowlo_writecow(cowdev
, req
->buffer
, len
, offset
);
1096 break; /* from switch */
1099 if ( (len
& MUMASK
) == 0) {
1100 DEBUGP(DCOW
"cowloop - write straight ");
1102 rv
= cowlo_writecow(cowdev
, req
->buffer
,
1108 rv
= cowlo_writemix(cowdev
, req
->buffer
, len
, offset
);
1112 rv
= 0; /* never happens */
1118 "cowloop - unrecognized command %d\n", *(req
->cmd
));
1122 return (rv
<= 0 ? 0 : 1);
1126 ** check for a given I/O-request if all underlying blocks
1127 ** (with size MAPUNIT) are either in the read-only file or in
1128 ** the cowfile (or a combination of the two)
1131 ** ALLRDO - all underlying blocks in rdofile
1132 ** ALLCOW - all underlying blocks in cowfile
1133 ** MIXEDUP - underlying blocks partly in rdofile and partly in cowfile
1136 cowlo_checkio(struct cowloop_device
*cowdev
, int len
, loff_t offset
)
1138 unsigned long mapnum
, bytenum
, bitnum
, blocknr
, partlen
;
1139 long int totcnt
, cowcnt
;
1143 ** notice that the requested block might cross
1144 ** a blocksize boundary while one of the concerned
1145 ** blocks resides in the read-only file and another
1146 ** one in the copy-on-write file; in that case the
1147 ** request will be broken up into pieces
1149 if ( (len
<= MAPUNIT
) &&
1150 (MAPUNIT
- (offset
& MUMASK
) <= len
) ) {
1153 ** requested data-block entirely fits within
1154 ** the mapunit used for the bitmap
1155 ** check if that block is located in rdofile or
1158 blocknr
= offset
>> MUSHIFT
;
1160 mapnum
= CALCMAP (blocknr
);
1161 bytenum
= CALCBYTE(blocknr
);
1162 bitnum
= CALCBIT (blocknr
);
1164 if (*(*(cowdev
->mapcache
+mapnum
)+bytenum
)&(1<<bitnum
))
1171 ** less easy situation:
1172 ** the requested data-block does not fit within the mapunit
1173 ** used for the bitmap
1174 ** check if *all* underlying blocks involved reside on the rdofile
1175 ** or the cowfile (so still no breakup required)
1177 for (cowcnt
=totcnt
=0; len
> 0; len
-=partlen
, offset
+=partlen
, totcnt
++){
1179 ** calculate blocknr of involved block
1181 blocknr
= offset
>> MUSHIFT
;
1184 ** calculate partial length for this transfer
1186 partlen
= MAPUNIT
- (offset
& MUMASK
);
1191 ** is this block located in the cowfile
1193 mapnum
= CALCMAP (blocknr
);
1194 bytenum
= CALCBYTE(blocknr
);
1195 bitnum
= CALCBIT (blocknr
);
1197 mc
= *(cowdev
->mapcache
+mapnum
);
1199 if (*(mc
+bytenum
)&(1<<bitnum
))
1203 "cowloop - check %lu - map %lu, byte %lu, bit %lu, "
1204 "cowcnt %ld, totcnt %ld %02x %p\n",
1205 blocknr
, mapnum
, bytenum
, bitnum
, cowcnt
, totcnt
,
1209 if (cowcnt
== 0) /* all involved blocks on rdofile? */
1212 if (cowcnt
== totcnt
) /* all involved blocks on cowfile? */
1216 ** situation somewhat more complicated:
1217 ** involved underlying blocks spread over both files
1223 ** read requested chunk partly from rdofile and partly from cowfile
1230 cowlo_readmix(struct cowloop_device
*cowdev
, void *buf
, int len
, loff_t offset
)
1232 unsigned long mapnum
, bytenum
, bitnum
, blocknr
, partlen
;
1237 ** complicated approach: breakup required of read-request
1239 for (rv
=1; len
> 0; len
-=partlen
, buf
+=partlen
, offset
+=partlen
) {
1241 ** calculate blocknr of entire block
1243 blocknr
= offset
>> MUSHIFT
;
1246 ** calculate partial length for this transfer
1248 partlen
= MAPUNIT
- (offset
& MUMASK
);
1253 ** is this block located in the cowfile
1255 mapnum
= CALCMAP (blocknr
);
1256 bytenum
= CALCBYTE(blocknr
);
1257 bitnum
= CALCBIT (blocknr
);
1258 mc
= *(cowdev
->mapcache
+mapnum
);
1260 if (*(mc
+bytenum
)&(1<<bitnum
)) {
1262 ** read (partial) block from cowfile
1264 DEBUGP(DCOW
"cowloop - split read "
1265 "cow partlen=%ld off=%lld\n", partlen
, offset
);
1267 if (cowlo_readcow(cowdev
, buf
, partlen
, offset
) <= 0)
1271 ** read (partial) block from rdofile
1273 DEBUGP(DCOW
"cowloop - split read "
1274 "rdo partlen=%ld off=%lld\n", partlen
, offset
);
1276 if (cowlo_readrdo(cowdev
, buf
, partlen
, offset
) <= 0)
1285 ** chunk to be written to the cowfile needs pieces to be
1286 ** read from the rdofile
1293 cowlo_writemix(struct cowloop_device
*cowdev
, void *buf
, int len
, loff_t offset
)
1295 unsigned long mapnum
, bytenum
, bitnum
, blocknr
, partlen
;
1300 ** somewhat more complicated stuff is required:
1301 ** if the request is larger than one underlying
1302 ** block or is spread over two underlying blocks,
1303 ** split the request into pieces; if a block does not
1304 ** start at a block boundary, take care that
1305 ** surrounding data is read first (if needed),
1306 ** fit the new data in and write it as a full block
1308 for (rv
=1; len
> 0; len
-=partlen
, buf
+=partlen
, offset
+=partlen
) {
1310 ** calculate partial length for this transfer
1312 partlen
= MAPUNIT
- (offset
& MUMASK
);
1317 ** calculate blocknr of entire block
1319 blocknr
= offset
>> MUSHIFT
;
1322 ** has this block been written before?
1324 mapnum
= CALCMAP (blocknr
);
1325 bytenum
= CALCBYTE(blocknr
);
1326 bitnum
= CALCBIT (blocknr
);
1327 mc
= *(cowdev
->mapcache
+mapnum
);
1329 if (*(mc
+bytenum
)&(1<<bitnum
)) {
1331 ** block has been written before;
1332 ** write transparantly to cowfile
1335 "cowloop - splitwr transp\n");
1337 if (cowlo_writecow(cowdev
, buf
, partlen
, offset
) <= 0)
1341 ** block has never been written before,
1342 ** so read entire block from
1343 ** read-only file first, unless
1344 ** a full block is requested to
1347 if (partlen
< MAPUNIT
) {
1348 if (cowlo_readrdo(cowdev
, cowdev
->iobuf
,
1349 MAPUNIT
, (loff_t
)blocknr
<< MUSHIFT
) <= 0)
1354 ** transfer modified part into
1355 ** the block just read
1357 memcpy(cowdev
->iobuf
+ (offset
& MUMASK
), buf
, partlen
);
1360 ** write entire block to cowfile
1362 DEBUGP(DCOW
"cowloop - split "
1363 "partlen=%ld off=%lld\n",
1364 partlen
, (loff_t
)blocknr
<< MUSHIFT
);
1366 if (cowlo_writecow(cowdev
, cowdev
->iobuf
, MAPUNIT
,
1367 (loff_t
)blocknr
<< MUSHIFT
) <= 0)
1375 /*****************************************************************************/
1376 /* I/O-support for read-only file and copy-on-write file */
1377 /*****************************************************************************/
1380 ** read data from the read-only file
1382 ** return-value: similar to user-mode read
1385 cowlo_readrdo(struct cowloop_device
*cowdev
, void *buf
, int len
, loff_t offset
)
1388 mm_segment_t old_fs
;
1389 loff_t saveoffset
= offset
;
1391 DEBUGP(DCOW
"cowloop - readrdo called\n");
1395 rv
= cowdev
->rdofp
->f_op
->read(cowdev
->rdofp
, buf
, len
, &offset
);
1399 printk(KERN_WARNING
"cowloop - read-failure %ld on rdofile"
1400 "- offset=%lld len=%d\n",
1401 rv
, saveoffset
, len
);
1409 ** read cowfile from a modified offset, i.e. skipping the bitmap and cowhead
1411 ** return-value: similar to user-mode read
1414 cowlo_readcow(struct cowloop_device
*cowdev
, void *buf
, int len
, loff_t offset
)
1416 DEBUGP(DCOW
"cowloop - readcow called\n");
1418 offset
+= cowdev
->cowhead
->doffset
;
1420 return cowlo_readcowraw(cowdev
, buf
, len
, offset
);
1424 ** read cowfile from an absolute offset
1426 ** return-value: similar to user-mode read
1429 cowlo_readcowraw(struct cowloop_device
*cowdev
,
1430 void *buf
, int len
, loff_t offset
)
1433 mm_segment_t old_fs
;
1434 loff_t saveoffset
= offset
;
1436 DEBUGP(DCOW
"cowloop - readcowraw called\n");
1439 ** be sure that cowfile is opened for read-write
1441 if ( !(cowdev
->state
& COWCOWOPEN
) ) {
1443 "cowloop - read request from cowfile refused\n");
1449 ** issue low level read
1453 rv
= cowdev
->cowfp
->f_op
->read(cowdev
->cowfp
, buf
, len
, &offset
);
1458 "cowloop - read-failure %ld on cowfile"
1459 "- offset=%lld len=%d\n", rv
, saveoffset
, len
);
1467 ** write cowfile from a modified offset, i.e. skipping the bitmap and cowhead
1469 ** if a block is written for the first time while its contents consists
1470 ** of binary zeroes only, the concerning bitmap is flushed to the cowfile
1472 ** return-value: similar to user-mode write
1475 cowlo_writecow(struct cowloop_device
*cowdev
, void *buf
, int len
, loff_t offset
)
1478 unsigned long mapnum
=0, mapbyte
=0, mapbit
=0, cowblock
=0, partlen
;
1479 char *tmpptr
, *mapptr
= NULL
;
1480 loff_t tmpoffset
, mapoffset
= 0;
1482 DEBUGP(DCOW
"cowloop - writecow called\n");
1485 ** be sure that cowfile is opened for read-write
1487 if ( !(cowdev
->state
& COWRWCOWOPEN
) ) {
1489 "cowloop - Write request to cowfile refused\n");
1495 ** write the entire block to the cowfile
1497 tmpoffset
= offset
+ cowdev
->cowhead
->doffset
;
1499 rv
= cowlo_writecowraw(cowdev
, buf
, len
, tmpoffset
);
1502 ** verify if enough space available on filesystem holding
1504 ** - when the last write failed (might be caused by lack of space)
1505 ** - when a watcher is active (to react adequatly)
1506 ** - when the previous check indicated fs was almost full
1507 ** - with regular intervals
1510 (cowdev
->state
& COWWATCHDOG
) ||
1511 (cowdev
->blkavail
/ 2 < SPCDFLINTVL
) ||
1512 (cowdev
->cowwrites
% SPCDFLINTVL
== 0) ) {
1515 if (vfs_statfs(cowdev
->cowfp
->f_dentry
, &ks
)==0){
1516 if (ks
.f_bavail
<= SPCMINBLK
) {
1517 switch (ks
.f_bavail
) {
1524 "ALERT: cowfile full!\n");
1529 "cowloop - cowfile almost "
1530 "full (only %llu Kb free)\n",
1531 (unsigned long long)
1532 ks
.f_bsize
* ks
.f_bavail
/1024);
1536 cowdev
->blktotal
= ks
.f_blocks
;
1537 cowdev
->blkavail
= ks
.f_bavail
;
1540 ** wakeup watcher if threshold has been reached
1542 if ( (cowdev
->state
& COWWATCHDOG
) &&
1543 (cowdev
->watchthresh
>= cowdev
->blkavail
) ) {
1544 wake_up_interruptible(&cowdev
->watchq
);
1552 DEBUGP(DCOW
"cowloop - block written\n");
1555 ** check if block(s) is/are written to the cowfile
1556 ** for the first time; if so, adapt the bitmap
1558 for (; len
> 0; len
-=partlen
, offset
+=partlen
, buf
+=partlen
) {
1560 ** calculate partial length for this transfer
1562 partlen
= MAPUNIT
- (offset
& MUMASK
);
1567 ** calculate bitnr of written chunk of cowblock
1569 cowblock
= offset
>> MUSHIFT
;
1571 mapnum
= CALCMAP (cowblock
);
1572 mapbyte
= CALCBYTE(cowblock
);
1573 mapbit
= CALCBIT (cowblock
);
1575 if (*(*(cowdev
->mapcache
+mapnum
)+mapbyte
) & (1<<mapbit
))
1576 continue; /* already written before */
1579 ** if the block is written for the first time,
1580 ** the corresponding bit should be set in the bitmap
1582 *(*(cowdev
->mapcache
+mapnum
)+mapbyte
) |= (1<<mapbit
);
1584 cowdev
->nrcowblocks
++;
1586 DEBUGP(DCOW
"cowloop - bitupdate blk=%ld map=%ld "
1587 "byte=%ld bit=%ld\n",
1588 cowblock
, mapnum
, mapbyte
, mapbit
);
1591 ** check if the cowhead in the cowfile is currently
1592 ** marked clean; if so, mark it dirty and flush it
1594 if ( !(cowdev
->cowhead
->flags
&= COWDIRTY
)) {
1595 cowdev
->cowhead
->flags
|= COWDIRTY
;
1597 cowlo_writecowraw(cowdev
, cowdev
->cowhead
,
1598 MAPUNIT
, (loff_t
)0);
1602 ** if the written datablock contained binary zeroes,
1603 ** the bitmap block should be marked to be flushed to disk
1604 ** (blocks containing all zeroes cannot be recovered by
1605 ** the cowrepair-program later on if cowloop is not properly
1606 ** removed via rmmod)
1608 if ( memcmp(buf
, allzeroes
, partlen
) ) /* not all zeroes? */
1609 continue; /* no flush needed */
1612 ** calculate positions of bitmap block to be flushed
1613 ** - pointer of bitmap block in memory
1614 ** - offset of bitmap block in cowfile
1616 tmpptr
= *(cowdev
->mapcache
+mapnum
) + (mapbyte
& (~MUMASK
));
1617 tmpoffset
= (loff_t
) MAPUNIT
+ mapnum
* MAPCHUNKSZ
+
1618 (mapbyte
& (~MUMASK
));
1621 ** flush a bitmap block at the moment that all bits have
1622 ** been set in that block, i.e. at the moment that we
1623 ** switch to another bitmap block
1625 if ( (mapoffset
!= 0) && (mapoffset
!= tmpoffset
) ) {
1626 if (cowlo_writecowraw(cowdev
, mapptr
, MAPUNIT
,
1629 "cowloop - write-failure on bitmap - "
1630 "blk=%ld map=%ld byte=%ld bit=%ld\n",
1631 cowblock
, mapnum
, mapbyte
, mapbit
);
1634 DEBUGP(DCOW
"cowloop - bitmap blk written %lld\n",
1639 ** remember offset in cowfile and offset in memory
1640 ** for bitmap to be flushed; flushing will be done
1641 ** as soon as all updates in this bitmap block have
1644 mapoffset
= tmpoffset
;
1649 ** any new block written containing binary zeroes?
1652 if (cowlo_writecowraw(cowdev
, mapptr
, MAPUNIT
, mapoffset
) < 0) {
1654 "cowloop - write-failure on bitmap - "
1655 "blk=%ld map=%ld byte=%ld bit=%ld\n",
1656 cowblock
, mapnum
, mapbyte
, mapbit
);
1659 DEBUGP(DCOW
"cowloop - bitmap block written %lld\n", mapoffset
);
1666 ** write cowfile from an absolute offset
1668 ** return-value: similar to user-mode write
1671 cowlo_writecowraw(struct cowloop_device
*cowdev
,
1672 void *buf
, int len
, loff_t offset
)
1675 mm_segment_t old_fs
;
1676 loff_t saveoffset
= offset
;
1678 DEBUGP(DCOW
"cowloop - writecowraw called\n");
1681 ** be sure that cowfile is opened for read-write
1683 if ( !(cowdev
->state
& COWRWCOWOPEN
) ) {
1685 "cowloop - write request to cowfile refused\n");
1691 ** issue low level write
1695 rv
= cowdev
->cowfp
->f_op
->write(cowdev
->cowfp
, buf
, len
, &offset
);
1700 "cowloop - write-failure %ld on cowfile"
1701 "- offset=%lld len=%d\n", rv
, saveoffset
, len
);
1704 cowdev
->cowwrites
++;
1710 ** readproc-function: called when the corresponding /proc-file is read
1713 cowlo_readproc(char *buf
, char **start
, off_t pos
, int cnt
, int *eof
, void *p
)
1715 struct cowloop_device
*cowdev
= p
;
1717 revision
[sizeof revision
- 3] = '\0';
1720 " cowloop version: %9s\n\n"
1721 " device state: %s%s%s%s\n"
1722 " number of opens: %9d\n"
1723 " pid of thread: %9d\n\n"
1724 " read-only file: %9s\n"
1725 " rdoreads: %9lu\n\n"
1726 "copy-on-write file: %9s\n"
1727 " state cowfile: %9s\n"
1728 " bitmap-blocks: %9lu (of %d bytes)\n"
1729 " cowblocks in use: %9lu (of %d bytes)\n"
1731 " cowwrites: %9lu\n",
1734 cowdev
->state
& COWDEVOPEN
? "devopen " : "",
1735 cowdev
->state
& COWRWCOWOPEN
? "cowopenrw " : "",
1736 cowdev
->state
& COWRDCOWOPEN
? "cowopenro " : "",
1737 cowdev
->state
& COWWATCHDOG
? "watchdog " : "",
1744 cowdev
->cowhead
->flags
& COWDIRTY
? "dirty":"clean",
1745 cowdev
->mapsize
>> MUSHIFT
, MAPUNIT
,
1746 cowdev
->nrcowblocks
, MAPUNIT
,
1751 /*****************************************************************************/
1752 /* Setup and destroy cowdevices */
1753 /*****************************************************************************/
1756 ** open and prepare a cowdevice (rdofile and cowfile) and allocate bitmaps
1760 ** < 0 - error value
1763 cowlo_openpair(char *rdof
, char *cowf
, int autorecover
, int minor
)
1766 struct cowloop_device
*cowdev
= cowdevall
[minor
];
1772 ** requested device exists?
1774 if (minor
>= maxcows
) {
1780 ** requested device already assigned to cowdevice?
1782 if (cowdev
->state
& COWDEVOPEN
) {
1788 ** initialize administration
1790 memset(cowdev
, 0, sizeof *cowdev
);
1792 spin_lock_init (&cowdev
->rqlock
);
1793 init_waitqueue_head(&cowdev
->waitq
);
1794 init_waitqueue_head(&cowdev
->watchq
);
1797 ** open the read-only file
1799 DEBUGP(DCOW
"cowloop - call openrdo....\n");
1801 if ( (rv
= cowlo_openrdo(cowdev
, rdof
)) ) {
1802 cowlo_undo_openrdo(cowdev
);
1810 DEBUGP(DCOW
"cowloop - call opencow....\n");
1812 if ( (rv
= cowlo_opencow(cowdev
, cowf
, autorecover
)) ) {
1813 cowlo_undo_openrdo(cowdev
);
1814 cowlo_undo_opencow(cowdev
);
1820 ** administer total and available size of filesystem holding cowfile
1822 if (vfs_statfs(cowdev
->cowfp
->f_dentry
, &ks
)==0) {
1823 cowdev
->blksize
= ks
.f_bsize
;
1824 cowdev
->blktotal
= ks
.f_blocks
;
1825 cowdev
->blkavail
= ks
.f_bavail
;
1827 cowdev
->blksize
= 1024; /* avoid division by zero */
1831 ** flush the (recovered) bitmaps and cowhead to the cowfile
1833 DEBUGP(DCOW
"cowloop - call cowsync....\n");
1838 ** allocate gendisk for the cow device
1840 DEBUGP(DCOW
"cowloop - alloc disk....\n");
1842 if ((cowdev
->gd
= alloc_disk(1)) == NULL
) {
1844 "cowloop - unable to alloc_disk for cowloop\n");
1846 cowlo_undo_openrdo(cowdev
);
1847 cowlo_undo_opencow(cowdev
);
1852 cowdev
->gd
->major
= COWMAJOR
;
1853 cowdev
->gd
->first_minor
= minor
;
1854 cowdev
->gd
->minors
= 1;
1855 cowdev
->gd
->fops
= &cowlo_fops
;
1856 cowdev
->gd
->private_data
= cowdev
;
1857 sprintf(cowdev
->gd
->disk_name
, "%s%d", DEVICE_NAME
, minor
);
1859 /* in .5 Kb units */
1860 set_capacity(cowdev
->gd
, (cowdev
->numblocks
*(MAPUNIT
/512)));
1862 DEBUGP(DCOW
"cowloop - init request queue....\n");
1864 if ((cowdev
->rqueue
= blk_init_queue(cowlo_request
, &cowdev
->rqlock
))
1867 "cowloop - unable to get request queue for cowloop\n");
1869 del_gendisk(cowdev
->gd
);
1870 cowlo_undo_openrdo(cowdev
);
1871 cowlo_undo_opencow(cowdev
);
1876 blk_queue_logical_block_size(cowdev
->rqueue
, cowdev
->blocksz
);
1877 cowdev
->gd
->queue
= cowdev
->rqueue
;
1880 ** start kernel thread to handle requests
1882 DEBUGP(DCOW
"cowloop - kickoff daemon....\n");
1884 cowdev
->pid
= kernel_thread((int (*)(void *))cowlo_daemon
, cowdev
, 0);
1887 ** create a file below directory /proc/cow for this new cowdevice
1889 if (cowlo_procdir
) {
1892 sprintf(tmpname
, "%d", minor
);
1894 create_proc_read_entry(tmpname
, 0 , cowlo_procdir
,
1895 cowlo_readproc
, cowdev
);
1898 cowdev
->state
|= COWDEVOPEN
;
1900 cowdev
->rdoname
= rdof
;
1901 cowdev
->cowname
= cowf
;
1904 ** enable the new disk; this triggers the first request!
1906 DEBUGP(DCOW
"cowloop - call add_disk....\n");
1908 add_disk(cowdev
->gd
);
1915 ** close a cowdevice (pair of rdofile/cowfile) and release memory
1919 ** < 0 - error value
1922 cowlo_closepair(struct cowloop_device
*cowdev
)
1929 ** if cowdevice is not activated at all, refuse
1931 if ( !(cowdev
->state
& COWDEVOPEN
) ) {
1937 ** if this cowdevice is still open, refuse
1939 if (cowdev
->opencnt
> 0) {
1947 ** wakeup watcher (if any)
1949 if (cowdev
->state
& COWWATCHDOG
) {
1950 cowdev
->watchthresh
= cowdev
->blkavail
;
1951 wake_up_interruptible(&cowdev
->watchq
);
1955 ** wakeup kernel-thread to be able to exit
1956 ** and wait until it has exited
1958 cowdev
->closedown
= 1;
1959 cowdev
->qfilled
= 1;
1960 wake_up_interruptible(&cowdev
->waitq
);
1965 del_gendisk(cowdev
->gd
); /* revert the alloc_disk() */
1966 put_disk(cowdev
->gd
); /* revert the add_disk() */
1968 if (cowlo_procdir
) {
1971 for (minor
= 0; minor
< maxcows
; minor
++) {
1972 if (cowdev
== cowdevall
[minor
]) break;
1974 sprintf(tmpname
, "%d", minor
);
1976 remove_proc_entry(tmpname
, cowlo_procdir
);
1979 blk_cleanup_queue(cowdev
->rqueue
);
1982 ** release memory for filenames if these names have
1983 ** been allocated dynamically
1985 if ( (cowdev
->cowname
) && (cowdev
->cowname
!= cowfile
))
1986 kfree(cowdev
->cowname
);
1988 if ( (cowdev
->rdoname
) && (cowdev
->rdoname
!= rdofile
))
1989 kfree(cowdev
->rdoname
);
1991 cowlo_undo_openrdo(cowdev
);
1992 cowlo_undo_opencow(cowdev
);
1994 cowdev
->state
&= ~COWDEVOPEN
;
2000 ** open the read-only file
2004 ** < 0 - error value
2007 cowlo_openrdo(struct cowloop_device
*cowdev
, char *rdof
)
2010 struct inode
*inode
;
2013 DEBUGP(DCOW
"cowloop - openrdo called\n");
2016 ** open the read-only file
2020 "cowloop - specify name for read-only file\n\n");
2024 f
= filp_open(rdof
, O_RDONLY
|O_LARGEFILE
, 0);
2026 if ( (f
== NULL
) || IS_ERR(f
) ) {
2028 "cowloop - open of rdofile %s failed\n", rdof
);
2034 inode
= f
->f_dentry
->d_inode
;
2036 if ( !S_ISREG(inode
->i_mode
) && !S_ISBLK(inode
->i_mode
) ) {
2038 "cowloop - %s not regular file or blockdev\n", rdof
);
2042 DEBUGP(DCOW
"cowloop - determine size rdo....\n");
2045 ** determine block-size and total size of read-only file
2047 if (S_ISREG(inode
->i_mode
)) {
2049 ** read-only file is a regular file
2051 cowdev
->blocksz
= 512; /* other value fails */
2052 cowdev
->numblocks
= inode
->i_size
>> MUSHIFT
;
2054 if (inode
->i_size
& MUMASK
) {
2056 "cowloop - rdofile %s truncated to multiple "
2057 "of %d bytes\n", rdof
, MAPUNIT
);
2060 DEBUGP(DCOW
"cowloop - RO=regular: numblocks=%d, blocksz=%d\n",
2061 cowdev
->numblocks
, cowdev
->blocksz
);
2064 ** read-only file is a block device
2066 cowdev
->belowdev
= inode
->i_bdev
;
2067 cowdev
->belowgd
= cowdev
->belowdev
->bd_disk
; /* gendisk */
2069 if (cowdev
->belowdev
->bd_part
) {
2070 cowdev
->numblocks
= cowdev
->belowdev
->bd_part
->nr_sects
2074 if (cowdev
->belowgd
) {
2075 cowdev
->belowq
= cowdev
->belowgd
->queue
;
2077 if (cowdev
->numblocks
== 0) {
2078 cowdev
->numblocks
= get_capacity(cowdev
->belowgd
)
2085 cowdev
->blocksz
= queue_logical_block_size(cowdev
->belowq
);
2087 if (cowdev
->blocksz
== 0)
2088 cowdev
->blocksz
= BLOCK_SIZE
; /* default 2^10 */
2090 DEBUGP(DCOW
"cowloop - numblocks=%d, "
2091 "blocksz=%d, belowgd=%p, belowq=%p\n",
2092 cowdev
->numblocks
, cowdev
->blocksz
,
2093 cowdev
->belowgd
, cowdev
->belowq
);
2095 DEBUGP(DCOW
"cowloop - belowdev.bd_block_size=%d\n",
2096 cowdev
->belowdev
->bd_block_size
);
2099 if (cowdev
->numblocks
== 0) {
2100 printk(KERN_ERR
"cowloop - %s has no contents\n", rdof
);
2105 ** reserve space in memory as generic I/O buffer
2107 cowdev
->iobuf
= kmalloc(MAPUNIT
, GFP_KERNEL
);
2109 if (!cowdev
->iobuf
) {
2111 "cowloop - cannot get space for buffer %d\n", MAPUNIT
);
2115 DEBUGP(DCOW
"cowloop - determine fingerprint rdo....\n");
2118 ** determine fingerprint for read-only file
2119 ** calculate fingerprint from first four datablocks
2120 ** which do not contain binary zeroes
2122 for (i
=0, cowdev
->fingerprint
=0, nrval
=0;
2123 (nrval
< 4)&&(i
< cowdev
->numblocks
); i
++) {
2130 if (cowlo_readrdo(cowdev
, cowdev
->iobuf
, MAPUNIT
,
2131 (loff_t
)i
<< MUSHIFT
) < 1)
2135 ** calculate fingerprint by adding all byte-values
2137 for (j
=0, cs
=0; j
< MAPUNIT
; j
++)
2138 cs
+= *(cowdev
->iobuf
+j
);
2140 if (cs
== 0) /* block probably contained zeroes */
2144 ** shift byte-value to proper place in final fingerprint
2146 cowdev
->fingerprint
|= cs
<< (nrval
*8);
2154 ** undo memory allocs and file opens issued so far
2155 ** related to the read-only file
2158 cowlo_undo_openrdo(struct cowloop_device
*cowdev
)
2161 kfree(cowdev
->iobuf
);
2164 filp_close(cowdev
->rdofp
, 0);
2172 ** < 0 - error value
2175 cowlo_opencow(struct cowloop_device
*cowdev
, char *cowf
, int autorecover
)
2181 struct inode
*inode
;
2183 struct cowloop_device
*cowtmp
;
2185 DEBUGP(DCOW
"cowloop - opencow called\n");
2188 ** open copy-on-write file (read-write)
2190 if (cowf
[0] == '\0') {
2192 "cowloop - specify name of copy-on-write file\n\n");
2196 f
= filp_open(cowf
, O_RDWR
|O_LARGEFILE
, 0600);
2198 if ( (f
== NULL
) || IS_ERR(f
) ) {
2200 ** non-existing cowfile: try to create
2202 f
= filp_open(cowf
, O_RDWR
|O_CREAT
|O_LARGEFILE
, 0600);
2204 if ( (f
== NULL
) || IS_ERR(f
) ) {
2206 "cowloop - failed to open file %s for read-write\n\n",
2214 inode
= f
->f_dentry
->d_inode
;
2216 if (!S_ISREG(inode
->i_mode
)) {
2217 printk(KERN_ERR
"cowloop - %s is not regular file\n", cowf
);
2222 ** check if this cowfile is already in use for another cowdevice
2224 for (minor
= 0; minor
< maxcows
; minor
++) {
2226 cowtmp
= cowdevall
[minor
];
2228 if ( !(cowtmp
->state
& COWDEVOPEN
) )
2231 if (cowtmp
== cowdev
)
2234 if (cowtmp
->cowfp
->f_dentry
->d_inode
== f
->f_dentry
->d_inode
) {
2236 "cowloop - %s: already in use as cow\n", cowf
);
2242 ** mark cowfile open for read-write
2244 cowdev
->state
|= COWRWCOWOPEN
;
2247 ** calculate size (in bytes) for total bitmap in cowfile;
2248 ** when the size of the cowhead block is added, the start-offset
2249 ** for the modified data blocks can be found
2251 nb
= cowdev
->numblocks
;
2253 if (nb
%8) /* transform #bits to #bytes */
2254 nb
+=8; /* rounded if necessary */
2257 if (nb
& MUMASK
) /* round up #bytes to MAPUNIT chunks */
2258 cowdev
->mapsize
= ( (nb
>>MUSHIFT
) +1) << MUSHIFT
;
2260 cowdev
->mapsize
= nb
;
2263 ** reserve space in memory for the cowhead
2265 cowdev
->cowhead
= kmalloc(MAPUNIT
, GFP_KERNEL
);
2267 if (!cowdev
->cowhead
) {
2268 printk(KERN_ERR
"cowloop - cannot get space for cowhead %d\n",
2273 memset(cowdev
->cowhead
, 0, MAPUNIT
);
2275 DEBUGP(DCOW
"cowloop - prepare cowhead....\n");
2278 ** check if the cowfile exists or should be created
2280 if (inode
->i_size
!= 0) {
2282 ** existing cowfile: read the cow head
2284 if (inode
->i_size
< MAPUNIT
) {
2286 "cowloop - existing cowfile %s too small\n",
2291 cowlo_readcowraw(cowdev
, cowdev
->cowhead
, MAPUNIT
, (loff_t
) 0);
2294 ** verify if the existing file is really a cowfile
2296 if (cowdev
->cowhead
->magic
!= COWMAGIC
) {
2298 "cowloop - cowfile %s has incorrect format\n",
2304 ** verify the cowhead version of the cowfile
2306 if (cowdev
->cowhead
->version
> COWVERSION
) {
2308 "cowloop - cowfile %s newer than this driver\n",
2314 ** make sure that this is not a packed cowfile
2316 if (cowdev
->cowhead
->flags
& COWPACKED
) {
2318 "cowloop - packed cowfile %s not accepted\n", cowf
);
2323 ** verify if the cowfile has been properly closed
2325 if (cowdev
->cowhead
->flags
& COWDIRTY
) {
2327 ** cowfile was not properly closed;
2328 ** check if automatic recovery is required
2329 ** (actual recovery will be done later on)
2333 "cowloop - cowfile %s is dirty "
2334 "(not properly closed by rmmod?)\n",
2337 "cowloop - run cowrepair or specify "
2338 "'option=r' to recover\n");
2344 ** verify if the cowfile is really related to this rdofile
2346 if (cowdev
->cowhead
->rdoblocks
!= cowdev
->numblocks
) {
2348 "cowloop - cowfile %s (size %lld) not related "
2349 "to rdofile (size %lld)\n",
2351 (long long)cowdev
->cowhead
->rdoblocks
<<MUSHIFT
,
2352 (long long)cowdev
->numblocks
<<MUSHIFT
);
2356 if (cowdev
->cowhead
->rdofingerprint
!= cowdev
->fingerprint
) {
2358 "cowloop - cowfile %s not related to rdofile "
2359 " (fingerprint err - rdofile modified?)\n", cowf
);
2364 ** new cowfile: determine the minimal size (cowhead+bitmap)
2366 offset
= (loff_t
) MAPUNIT
+ cowdev
->mapsize
- 1;
2368 if ( cowlo_writecowraw(cowdev
, "", 1, offset
) < 1) {
2370 "cowloop - cannot set cowfile to size %lld\n",
2376 ** prepare new cowhead
2378 cowdev
->cowhead
->magic
= COWMAGIC
;
2379 cowdev
->cowhead
->version
= COWVERSION
;
2380 cowdev
->cowhead
->mapunit
= MAPUNIT
;
2381 cowdev
->cowhead
->mapsize
= cowdev
->mapsize
;
2382 cowdev
->cowhead
->rdoblocks
= cowdev
->numblocks
;
2383 cowdev
->cowhead
->rdofingerprint
= cowdev
->fingerprint
;
2384 cowdev
->cowhead
->cowused
= 0;
2387 ** calculate start offset of data in cowfile,
2388 ** rounded up to multiple of 4K to avoid
2389 ** unnecessary disk-usage for written datablocks in
2390 ** the sparsed cowfile on e.g. 4K filesystems
2392 cowdev
->cowhead
->doffset
=
2393 ((MAPUNIT
+cowdev
->mapsize
+4095)>>12)<<12;
2396 cowdev
->cowhead
->flags
= 0;
2398 DEBUGP(DCOW
"cowloop - reserve space bitmap....\n");
2401 ** reserve space in memory for the entire bitmap and
2402 ** fill it with the bitmap-data from disk; the entire
2403 ** bitmap is allocated in several chunks because kmalloc
2404 ** has restrictions regarding the allowed size per kmalloc
2406 cowdev
->mapcount
= (cowdev
->mapsize
+MAPCHUNKSZ
-1)/MAPCHUNKSZ
;
2409 ** the size of every bitmap chunk will be MAPCHUNKSZ bytes, except for
2410 ** the last bitmap chunk: calculate remaining size for this chunk
2412 if (cowdev
->mapsize
% MAPCHUNKSZ
== 0)
2413 cowdev
->mapremain
= MAPCHUNKSZ
;
2415 cowdev
->mapremain
= cowdev
->mapsize
% MAPCHUNKSZ
;
2418 ** allocate space to store all pointers for the bitmap-chunks
2419 ** (initialize area with zeroes to allow proper undo)
2421 cowdev
->mapcache
= kmalloc(cowdev
->mapcount
* sizeof(char *),
2423 if (!cowdev
->mapcache
) {
2425 "cowloop - can not allocate space for bitmap ptrs\n");
2429 memset(cowdev
->mapcache
, 0, cowdev
->mapcount
* sizeof(char *));
2432 ** allocate space to store the bitmap-chunks themselves
2434 for (i
=0; i
< cowdev
->mapcount
; i
++) {
2435 if (i
< (cowdev
->mapcount
-1))
2436 *(cowdev
->mapcache
+i
) = kmalloc(MAPCHUNKSZ
, GFP_KERNEL
);
2438 *(cowdev
->mapcache
+i
) = kmalloc(cowdev
->mapremain
,
2441 if (*(cowdev
->mapcache
+i
) == NULL
) {
2442 printk(KERN_ERR
"cowloop - no space for bitmapchunk %ld"
2443 " totmapsz=%ld, mapcnt=%d mapunit=%d\n",
2444 i
, cowdev
->mapsize
, cowdev
->mapcount
,
2450 DEBUGP(DCOW
"cowloop - read bitmap from cow....\n");
2453 ** read the entire bitmap from the cowfile into the in-memory cache;
2454 ** count the number of blocks that are in use already
2455 ** (statistical purposes)
2457 for (i
=0, offset
=MAPUNIT
; i
< cowdev
->mapcount
;
2458 i
++, offset
+=MAPCHUNKSZ
) {
2459 unsigned long numbytes
;
2461 if (i
< (cowdev
->mapcount
-1))
2463 ** full bitmap chunk
2465 numbytes
= MAPCHUNKSZ
;
2468 ** last bitmap chunk: might be partly filled
2470 numbytes
= cowdev
->mapremain
;
2472 cowlo_readcowraw(cowdev
, *(cowdev
->mapcache
+i
),
2477 ** if the cowfile was dirty and automatic recovery is required,
2478 ** reconstruct a proper bitmap in memory now
2480 if (cowdev
->cowhead
->flags
& COWDIRTY
) {
2481 unsigned long long blocknum
;
2482 char databuf
[MAPUNIT
];
2483 unsigned long mapnum
, mapbyte
, mapbit
;
2485 printk(KERN_NOTICE
"cowloop - recover dirty cowfile %s....\n",
2489 ** read all data blocks
2491 for (blocknum
=0, rv
=1, offset
=0;
2492 cowlo_readcow(cowdev
, databuf
, MAPUNIT
, offset
) > 0;
2493 blocknum
++, offset
+= MAPUNIT
) {
2496 ** if this datablock contains real data (not binary
2497 ** zeroes), set the corresponding bit in the bitmap
2499 if ( memcmp(databuf
, allzeroes
, MAPUNIT
) == 0)
2502 mapnum
= CALCMAP (blocknum
);
2503 mapbyte
= CALCBYTE(blocknum
);
2504 mapbit
= CALCBIT (blocknum
);
2506 *(*(cowdev
->mapcache
+mapnum
)+mapbyte
) |= (1<<mapbit
);
2509 printk(KERN_NOTICE
"cowloop - cowfile recovery completed\n");
2513 ** count all bits set in the bitmaps for statistical purposes
2515 for (i
=0, cowdev
->nrcowblocks
= 0; i
< cowdev
->mapcount
; i
++) {
2519 if (i
< (cowdev
->mapcount
-1))
2520 numbytes
= MAPCHUNKSZ
;
2522 numbytes
= cowdev
->mapremain
;
2524 p
= *(cowdev
->mapcache
+i
);
2526 for (numbytes
--; numbytes
>= 0; numbytes
--, p
++) {
2528 ** for only eight checks the following construction
2529 ** is faster than a loop-construction
2531 if ((*p
) & 0x01) cowdev
->nrcowblocks
++;
2532 if ((*p
) & 0x02) cowdev
->nrcowblocks
++;
2533 if ((*p
) & 0x04) cowdev
->nrcowblocks
++;
2534 if ((*p
) & 0x08) cowdev
->nrcowblocks
++;
2535 if ((*p
) & 0x10) cowdev
->nrcowblocks
++;
2536 if ((*p
) & 0x20) cowdev
->nrcowblocks
++;
2537 if ((*p
) & 0x40) cowdev
->nrcowblocks
++;
2538 if ((*p
) & 0x80) cowdev
->nrcowblocks
++;
2543 ** consistency-check for number of bits set in bitmap
2545 if ( !(cowdev
->cowhead
->flags
& COWDIRTY
) &&
2546 (cowdev
->cowhead
->cowused
!= cowdev
->nrcowblocks
) ) {
2547 printk(KERN_ERR
"cowloop - inconsistent cowfile admi\n");
2555 ** undo memory allocs and file opens issued so far
2556 ** related to the cowfile
2559 cowlo_undo_opencow(struct cowloop_device
*cowdev
)
2563 if (cowdev
->mapcache
) {
2564 for (i
=0; i
< cowdev
->mapcount
; i
++) {
2565 if (*(cowdev
->mapcache
+i
) != NULL
)
2566 kfree( *(cowdev
->mapcache
+i
) );
2569 kfree(cowdev
->mapcache
);
2572 if (cowdev
->cowhead
)
2573 kfree(cowdev
->cowhead
);
2575 if ( (cowdev
->state
& COWCOWOPEN
) && (cowdev
->cowfp
) )
2576 filp_close(cowdev
->cowfp
, 0);
2579 ** mark cowfile closed
2581 cowdev
->state
&= ~COWCOWOPEN
;
2585 ** flush the entire bitmap and the cowhead (clean) to the cowfile
2587 ** must be called with the cowdevices-lock set
2594 struct cowloop_device
*cowdev
;
2596 for (minor
=0; minor
< maxcows
; minor
++) {
2597 cowdev
= cowdevall
[minor
];
2598 if ( ! (cowdev
->state
& COWRWCOWOPEN
) )
2601 for (i
=0, offset
=MAPUNIT
; i
< cowdev
->mapcount
;
2602 i
++, offset
+= MAPCHUNKSZ
) {
2603 unsigned long numbytes
;
2605 if (i
< (cowdev
->mapcount
-1))
2607 ** full bitmap chunk
2609 numbytes
= MAPCHUNKSZ
;
2612 ** last bitmap chunk: might be partly filled
2614 numbytes
= cowdev
->mapremain
;
2617 "cowloop - flushing bitmap %2d (%3ld Kb)\n",
2620 if (cowlo_writecowraw(cowdev
, *(cowdev
->mapcache
+i
),
2621 numbytes
, offset
) < numbytes
) {
2627 ** flush clean up-to-date cowhead to cowfile
2629 cowdev
->cowhead
->cowused
= cowdev
->nrcowblocks
;
2630 cowdev
->cowhead
->flags
&= ~COWDIRTY
;
2632 DEBUGP(DCOW
"cowloop - flushing cowhead (%3d Kb)\n",
2635 cowlo_writecowraw(cowdev
, cowdev
->cowhead
, MAPUNIT
, (loff_t
) 0);
2639 /*****************************************************************************/
2640 /* Module loading/unloading */
2641 /*****************************************************************************/
2644 ** called during insmod/modprobe
2647 cowlo_init_module(void)
2650 int minor
, uptocows
;
2652 revision
[sizeof revision
- 3] = '\0';
2654 printk(KERN_NOTICE
"cowloop - (C) 2009 ATComputing.nl - version: %s\n", &revision
[11]);
2655 printk(KERN_NOTICE
"cowloop - info: www.ATComputing.nl/cowloop\n");
2657 memset(allzeroes
, 0, MAPUNIT
);
2660 ** Setup administration for all possible cowdevices.
2661 ** Note that their minor numbers go from 0 to MAXCOWS-1 inclusive
2662 ** and minor == MAXCOWS-1 is reserved for the control device.
2664 if ((maxcows
< 1) || (maxcows
> MAXCOWS
)) {
2666 "cowloop - maxcows exceeds maximum of %d\n", MAXCOWS
);
2671 /* allocate room for a table with a pointer to each cowloop_device: */
2672 if ( (cowdevall
= kmalloc(maxcows
* sizeof(struct cowloop_device
*),
2673 GFP_KERNEL
)) == NULL
) {
2675 "cowloop - can not alloc table for %d devs\n", maxcows
);
2680 memset(cowdevall
, 0, maxcows
* sizeof(struct cowloop_device
*));
2681 /* then hook an actual cowloop_device struct to each pointer: */
2682 for (minor
=0; minor
< maxcows
; minor
++) {
2683 if ((cowdevall
[minor
] = kmalloc(sizeof(struct cowloop_device
),
2684 GFP_KERNEL
)) == NULL
) {
2686 "cowloop - can not alloc admin-struct for dev no %d\n", minor
);
2688 uptocows
= minor
; /* this is how far we got.... */
2692 memset(cowdevall
[minor
], 0, sizeof(struct cowloop_device
));
2694 uptocows
= maxcows
; /* we got all devices */
2696 sema_init(&cowdevlock
, 1);
2699 ** register cowloop module
2701 if ( register_blkdev(COWMAJOR
, DEVICE_NAME
) < 0) {
2703 "cowloop - unable to get major %d for cowloop\n", COWMAJOR
);
2709 ** create a directory below /proc to allocate a file
2710 ** for each cowdevice that is allocated later on
2712 cowlo_procdir
= proc_mkdir("cow", NULL
);
2715 ** check if a cowdevice has to be opened during insmod/modprobe;
2716 ** two parameters should be specified then: rdofile= and cowfile=
2718 if( (rdofile
[0] != '\0') && (cowfile
[0] != '\0') ) {
2720 int wantrecover
= 0;
2723 ** check if automatic recovery is wanted
2734 ** open new cowdevice with minor number 0
2736 if ( (rv
= cowlo_openpair(rdofile
, cowfile
, wantrecover
, 0))) {
2737 remove_proc_entry("cow", NULL
);
2738 unregister_blkdev(COWMAJOR
, DEVICE_NAME
);
2743 ** check if only one parameter has been specified
2745 if( (rdofile
[0] != '\0') || (cowfile
[0] != '\0') ) {
2747 "cowloop - only one filename specified\n");
2748 remove_proc_entry("cow", NULL
);
2749 unregister_blkdev(COWMAJOR
, DEVICE_NAME
);
2756 ** allocate fake disk as control channel to handle the requests
2757 ** to activate and deactivate cowdevices dynamically
2759 if (!(cowctlgd
= alloc_disk(1))) {
2761 "cowloop - unable to alloc_disk for cowctl\n");
2763 remove_proc_entry("cow", NULL
);
2764 (void) cowlo_closepair(cowdevall
[0]);
2765 unregister_blkdev(COWMAJOR
, DEVICE_NAME
);
2770 spin_lock_init(&cowctlrqlock
);
2771 cowctlgd
->major
= COWMAJOR
;
2772 cowctlgd
->first_minor
= COWCTL
;
2773 cowctlgd
->minors
= 1;
2774 cowctlgd
->fops
= &cowlo_fops
;
2775 cowctlgd
->private_data
= NULL
;
2776 /* the device has capacity 0, so there will be no q-requests */
2777 cowctlgd
->queue
= blk_init_queue(NULL
, &cowctlrqlock
);
2778 sprintf(cowctlgd
->disk_name
, "cowctl");
2779 set_capacity(cowctlgd
, 0);
2783 printk(KERN_NOTICE
"cowloop - number of configured cowdevices: %d\n",
2785 if (rdofile
[0] != '\0') {
2786 printk(KERN_NOTICE
"cowloop - initialized on rdofile=%s\n",
2789 printk(KERN_NOTICE
"cowloop - initialized without rdofile yet\n");
2794 for (minor
=0; minor
< uptocows
; minor
++) {
2795 kfree(cowdevall
[minor
]);
2802 ** called during rmmod
2805 cowlo_cleanup_module(void)
2810 ** flush bitmaps and cowheads to the cowfiles
2817 ** close all cowdevices
2819 for (minor
=0; minor
< maxcows
; minor
++)
2820 (void) cowlo_closepair(cowdevall
[minor
]);
2822 unregister_blkdev(COWMAJOR
, DEVICE_NAME
);
2825 ** get rid of /proc/cow and unregister the driver
2827 remove_proc_entry("cow", NULL
);
2829 for (minor
= 0; minor
< maxcows
; minor
++) {
2830 kfree(cowdevall
[minor
]);
2834 del_gendisk(cowctlgd
); /* revert the alloc_disk() */
2835 put_disk (cowctlgd
); /* revert the add_disk() */
2836 blk_cleanup_queue(cowctlgd
->queue
); /* cleanup the empty queue */
2838 printk(KERN_NOTICE
"cowloop - unloaded\n");
2841 module_init(cowlo_init_module
);
2842 module_exit(cowlo_cleanup_module
);