aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorH.J. Thomassen <hjt@ATComputing.nl>2009-08-25 18:39:04 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-15 15:02:33 -0400
commitdbda83255cf6a12d06527131214c123ee7ae96b9 (patch)
tree54e507163169416c8080675a99b12ec00d80e50b /drivers/staging
parentfa052e912d4d575b86a7fd3623380aba897a1a8e (diff)
Staging: add cowloop driver
Cowloop is a "copy-on-write" pseudo block driver. It can be stacked on top of a "real" block driver, and catches all write operations on their way from the file systems layer above to the real driver below, effectively shielding the lower driver from those write accesses. The requests are then diverted to an ordinary file, located somewhere else (configurable). Later read requests are checked to see whether they can be serviced by the "real" block driver below, or must be pulled in from the diverted location. More information is on the project's website http://www.ATComputing.nl/cowloop/ From: "H.J. Thomassen" <hjt@ATComputing.nl> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/cowloop/cowloop.c2897
-rw-r--r--drivers/staging/cowloop/cowloop.h66
2 files changed, 2963 insertions, 0 deletions
diff --git a/drivers/staging/cowloop/cowloop.c b/drivers/staging/cowloop/cowloop.c
new file mode 100644
index 000000000000..23978012838a
--- /dev/null
+++ b/drivers/staging/cowloop/cowloop.c
@@ -0,0 +1,2897 @@
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: */
125char 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
272MODULE_LICENSE("GPL");
273/* MODULE_AUTHOR("Gerlof Langeveld <gerlof@ATComputing.nl>"); obsolete address */
274MODULE_AUTHOR("Hendrik-Jan Thomassen <hjt@ATComputing.nl>"); /* current maintainer */
275MODULE_DESCRIPTION("Copy-on-write loop driver");
276MODULE_PARM_DESC(maxcows, " Number of configured cowdevices (default 16)");
277MODULE_PARM_DESC(rdofile, " Read-only file for /dev/cow/0");
278MODULE_PARM_DESC(cowfile, " Cowfile for /dev/cow/0");
279MODULE_PARM_DESC(option, " Repair cowfile if inconsistent: option=r");
280
281#define DEVICE_NAME "cow"
282
283#define DFLCOWS 16 /* default cowloop devices */
284
285static int maxcows = DFLCOWS;
286module_param(maxcows, int, 0);
287static char *rdofile = "";
288module_param(rdofile, charp, 0);
289static char *cowfile = "";
290module_param(cowfile, charp, 0);
291static char *option = "";
292module_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
315static 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
329struct 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
400static struct cowloop_device **cowdevall; /* ptr to ptrs to all cowdevices */
401static struct semaphore cowdevlock; /* generic lock for cowdevs */
402
403static struct gendisk *cowctlgd; /* gendisk control channel */
404static spinlock_t cowctlrqlock; /* for req.q. of ctrl. channel */
405
406/*
407** private directory /proc/cow
408*/
409struct proc_dir_entry *cowlo_procdir;
410
411/*
412** function prototypes
413*/
414static long int cowlo_do_request (struct request *req);
415static void cowlo_sync (void);
416static int cowlo_checkio (struct cowloop_device *, int, loff_t);
417static int cowlo_readmix (struct cowloop_device *, void *, int, loff_t);
418static int cowlo_writemix (struct cowloop_device *, void *, int, loff_t);
419static long int cowlo_readrdo (struct cowloop_device *, void *, int, loff_t);
420static long int cowlo_readcow (struct cowloop_device *, void *, int, loff_t);
421static long int cowlo_readcowraw (struct cowloop_device *, void *, int, loff_t);
422static long int cowlo_writecow (struct cowloop_device *, void *, int, loff_t);
423static long int cowlo_writecowraw(struct cowloop_device *, void *, int, loff_t);
424
425#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
426static int cowlo_ioctl (struct block_device *, fmode_t,
427 unsigned int, unsigned long);
428#else
429static int cowlo_ioctl (struct inode *, struct file *,
430 unsigned int, unsigned long);
431#endif
432
433static int cowlo_makepair (struct cowpair __user *);
434static int cowlo_removepair (unsigned long __user *);
435static int cowlo_watch (struct cowpair __user *);
436static int cowlo_cowctl (unsigned long __user *, int);
437static int cowlo_openpair (char *, char *, int, int);
438static int cowlo_closepair (struct cowloop_device *);
439static int cowlo_openrdo (struct cowloop_device *, char *);
440static int cowlo_opencow (struct cowloop_device *, char *, int);
441static void cowlo_undo_openrdo(struct cowloop_device *);
442static 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*/
455static int
456#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
457cowlo_open(struct block_device *bdev, fmode_t mode)
458#else
459cowlo_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*/
500static int
501#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
502cowlo_release(struct gendisk *gd, fmode_t mode)
503#else
504cowlo_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*/
532static int
533#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
534cowlo_ioctl(struct block_device *bdev, fmode_t mode,
535 unsigned int cmd, unsigned long arg)
536#else
537cowlo_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
621static 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*/
637static int
638cowlo_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*/
736static int
737cowlo_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*/
783static int
784cowlo_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*/
857static int
858cowlo_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*/
958static void
959#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25))
960cowlo_request(struct request_queue *q)
961#else
962cowlo_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 = elv_next_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 end_request(req, 0);
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 end_request(req, 0); /* 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*/
1017static int
1018cowlo_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 end_request(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*/
1082static long int
1083cowlo_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 = req->current_nr_sectors << 9;
1094 offset = (loff_t) req->sector << 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*/
1172static int
1173cowlo_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*/
1266static int
1267cowlo_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*/
1329static int
1330cowlo_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*/
1421static long int
1422cowlo_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*/
1450static long int
1451cowlo_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*/
1465static long int
1466cowlo_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*/
1511static long int
1512cowlo_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*/
1711static long int
1712cowlo_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*/
1753static int
1754cowlo_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*/
1803static int
1804cowlo_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_hardsect_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*/
1966static int
1967cowlo_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*/
2051static int
2052cowlo_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 = cowdev->belowq->hardsect_size;
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*/
2207static void
2208cowlo_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*/
2224static int
2225cowlo_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*/
2608static void
2609cowlo_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*/
2639static void
2640cowlo_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*/
2696static int __init
2697cowlo_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
2843error_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*/
2854static void __exit
2855cowlo_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
2896module_init(cowlo_init_module);
2897module_exit(cowlo_cleanup_module);
diff --git a/drivers/staging/cowloop/cowloop.h b/drivers/staging/cowloop/cowloop.h
new file mode 100644
index 000000000000..bbd4a35ac667
--- /dev/null
+++ b/drivers/staging/cowloop/cowloop.h
@@ -0,0 +1,66 @@
1/*
2** DO NOT MODIFY THESE VALUES (would make old cowfiles unusable)
3*/
4#define MAPUNIT 1024 /* blocksize for bit in bitmap */
5#define MUSHIFT 10 /* bitshift for bit in bitmap */
6#define MUMASK 0x3ff /* bitmask for bit in bitmap */
7
8#define COWMAGIC 0x574f437f /* byte-swapped '7f C O W' */
9#define COWDIRTY 0x01
10#define COWPACKED 0x02
11#define COWVERSION 1
12
13struct cowhead
14{
15 int magic; /* identifies a cowfile */
16 short version; /* version of cowhead */
17 short flags; /* flags indicating status */
18 unsigned long mapunit; /* blocksize per bit in bitmap */
19 unsigned long mapsize; /* total size of bitmap (bytes) */
20 unsigned long doffset; /* start-offset datablocks in cow */
21 unsigned long rdoblocks; /* size of related read-only file */
22 unsigned long rdofingerprint; /* fingerprint of read-only file */
23 unsigned long cowused; /* number of datablocks used in cow */
24};
25
26#define COWDEVDIR "/dev/cow/"
27#define COWDEVICE COWDEVDIR "%ld"
28#define COWCONTROL COWDEVDIR "ctl"
29
30#define MAXCOWS 1024
31#define COWCTL (MAXCOWS-1) /* minor number of /dev/cow/ctl */
32
33#define COWPROCDIR "/proc/cow/"
34#define COWPROCFILE COWPROCDIR "%d"
35
36/*
37** ioctl related stuff
38*/
39#define ANYDEV ((unsigned long)-1)
40
41struct cowpair
42{
43 unsigned char *rdofile; /* pathname of the rdofile */
44 unsigned char *cowfile; /* pathname of the cowfile */
45 unsigned short rdoflen; /* length of rdofile pathname */
46 unsigned short cowflen; /* length of cowfile pathname */
47 unsigned long device; /* requested/returned device number */
48};
49
50struct cowwatch
51{
52 int flags; /* request flags */
53 unsigned long device; /* requested device number */
54 unsigned long threshold; /* continue if free Kb < threshold */
55 unsigned long totalkb; /* ret: total filesystem size (Kb) */
56 unsigned long availkb; /* ret: free filesystem size (Kb) */
57};
58
59#define WATCHWAIT 0x01 /* block until threshold reached */
60
61#define COWSYNC _IO ('C', 1)
62#define COWMKPAIR _IOW ('C', 2, struct cowpair)
63#define COWRMPAIR _IOW ('C', 3, unsigned long)
64#define COWWATCH _IOW ('C', 4, struct cowwatch)
65#define COWCLOSE _IOW ('C', 5, unsigned long)
66#define COWRDOPEN _IOW ('C', 6, unsigned long)