Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.32-rc2 2842 lines 72 kB view raw
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#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> 265 266#include "cowloop.h" 267 268MODULE_LICENSE("GPL"); 269/* MODULE_AUTHOR("Gerlof Langeveld <gerlof@ATComputing.nl>"); obsolete address */ 270MODULE_AUTHOR("Hendrik-Jan Thomassen <hjt@ATComputing.nl>"); /* current maintainer */ 271MODULE_DESCRIPTION("Copy-on-write loop driver"); 272MODULE_PARM_DESC(maxcows, " Number of configured cowdevices (default 16)"); 273MODULE_PARM_DESC(rdofile, " Read-only file for /dev/cow/0"); 274MODULE_PARM_DESC(cowfile, " Cowfile for /dev/cow/0"); 275MODULE_PARM_DESC(option, " Repair cowfile if inconsistent: option=r"); 276 277#define DEVICE_NAME "cow" 278 279#define DFLCOWS 16 /* default cowloop devices */ 280 281static int maxcows = DFLCOWS; 282module_param(maxcows, int, 0); 283static char *rdofile = ""; 284module_param(rdofile, charp, 0); 285static char *cowfile = ""; 286module_param(cowfile, charp, 0); 287static char *option = ""; 288module_param(option, charp, 0); 289 290/* 291** per cowdevice several bitmap chunks are allowed of MAPCHUNKSZ each 292** 293** each bitmap chunk can describe MAPCHUNKSZ * 8 * MAPUNIT bytes of data 294** suppose: 295** MAPCHUNKSZ 4096 and MAPUNIT 1024 --> 4096 * 8 * 1024 = 32 Mb per chunk 296*/ 297#define MAPCHUNKSZ 4096 /* #bytes per bitmap chunk (do not change) */ 298 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 */ 302 303#define CALCMAP(x) ((x)/(MAPCHUNKSZ*8)) 304#define CALCBYTE(x) (((x)%(MAPCHUNKSZ*8))>>3) 305#define CALCBIT(x) ((x)&7) 306 307#define ALLCOW 1 308#define ALLRDO 2 309#define MIXEDUP 3 310 311static char allzeroes[MAPUNIT]; 312 313/* 314** administration per cowdevice (pair of cowfile/rdofile) 315*/ 316 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 */ 322 323#define COWCOWOPEN (COWRWCOWOPEN|COWRDCOWOPEN) 324 325struct cowloop_device 326{ 327 /* 328 ** current status 329 */ 330 int state; /* bit-values (see above) */ 331 int opencnt; /* # opens for cowdevice */ 332 333 /* 334 ** open file pointers 335 */ 336 struct file *rdofp, *cowfp; /* open file pointers */ 337 char *rdoname, *cowname; /* file names */ 338 339 /* 340 ** request queue administration 341 */ 342 struct request_queue *rqueue; 343 spinlock_t rqlock; 344 struct gendisk *gd; 345 346 /* 347 ** administration about read-only file 348 */ 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 */ 355 356 /* 357 ** bitmap administration to register which blocks are modified 358 */ 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 */ 363 364 char *iobuf; /* databuffer of MAPUNIT bytes */ 365 struct cowhead *cowhead; /* buffer containing cowhead */ 366 367 /* 368 ** administration for interface with the kernel-thread 369 */ 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 */ 376 377 /* 378 ** administration to keep track of free space in cowfile filesystem 379 */ 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) */ 383 384 wait_queue_head_t watchq; /* wait-Q: watcher awaits threshold */ 385 unsigned long watchthresh; /* threshold of watcher (blocks) */ 386 387 /* 388 ** statistical counters 389 */ 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 */ 394}; 395 396static struct cowloop_device **cowdevall; /* ptr to ptrs to all cowdevices */ 397static struct semaphore cowdevlock; /* generic lock for cowdevs */ 398 399static struct gendisk *cowctlgd; /* gendisk control channel */ 400static spinlock_t cowctlrqlock; /* for req.q. of ctrl. channel */ 401 402/* 403** private directory /proc/cow 404*/ 405struct proc_dir_entry *cowlo_procdir; 406 407/* 408** function prototypes 409*/ 410static long int cowlo_do_request (struct request *req); 411static void cowlo_sync (void); 412static int cowlo_checkio (struct cowloop_device *, int, loff_t); 413static int cowlo_readmix (struct cowloop_device *, void *, int, loff_t); 414static int cowlo_writemix (struct cowloop_device *, void *, int, loff_t); 415static long int cowlo_readrdo (struct cowloop_device *, void *, int, loff_t); 416static long int cowlo_readcow (struct cowloop_device *, void *, int, loff_t); 417static long int cowlo_readcowraw (struct cowloop_device *, void *, int, loff_t); 418static long int cowlo_writecow (struct cowloop_device *, void *, int, loff_t); 419static long int cowlo_writecowraw(struct cowloop_device *, void *, int, loff_t); 420static int cowlo_ioctl (struct block_device *, fmode_t, 421 unsigned int, unsigned long); 422static int cowlo_makepair (struct cowpair __user *); 423static int cowlo_removepair (unsigned long __user *); 424static int cowlo_watch (struct cowpair __user *); 425static int cowlo_cowctl (unsigned long __user *, int); 426static int cowlo_openpair (char *, char *, int, int); 427static int cowlo_closepair (struct cowloop_device *); 428static int cowlo_openrdo (struct cowloop_device *, char *); 429static int cowlo_opencow (struct cowloop_device *, char *, int); 430static void cowlo_undo_openrdo(struct cowloop_device *); 431static void cowlo_undo_opencow(struct cowloop_device *); 432 433/*****************************************************************************/ 434/* System call handling */ 435/*****************************************************************************/ 436 437/* 438** handle system call open()/mount() 439** 440** returns: 441** 0 - okay 442** < 0 - error value 443*/ 444static int cowlo_open(struct block_device *bdev, fmode_t mode) 445{ 446 struct inode *inode = bdev->bd_inode; 447 448 if (!inode) 449 return -EINVAL; 450 451 if (imajor(inode) != COWMAJOR) { 452 printk(KERN_WARNING 453 "cowloop - unexpected major %d\n", imajor(inode)); 454 return -ENODEV; 455 } 456 457 switch (iminor(inode)) { 458 case COWCTL: 459 DEBUGP(DCOW"cowloop - open %d control\n", COWCTL); 460 break; 461 462 default: 463 DEBUGP(DCOW"cowloop - open minor %d\n", iminor(inode)); 464 465 if ( iminor(inode) >= maxcows ) 466 return -ENODEV; 467 468 if ( !((cowdevall[iminor(inode)])->state & COWDEVOPEN) ) 469 return -ENODEV; 470 471 (cowdevall[iminor(inode)])->opencnt++; 472 } 473 474 return 0; 475} 476 477/* 478** handle system call close()/umount() 479** 480** returns: 481** 0 - okay 482*/ 483static int cowlo_release(struct gendisk *gd, fmode_t mode) 484{ 485 struct block_device *bdev; 486 struct inode *inode; 487 488 bdev = bdget_disk(gd, 0); 489 inode = bdev->bd_inode; 490 if (!inode) 491 return 0; 492 493 DEBUGP(DCOW"cowloop - release (close) minor %d\n", iminor(inode)); 494 495 if ( iminor(inode) != COWCTL) 496 (cowdevall[iminor(inode)])->opencnt--; 497 498 return 0; 499} 500 501/* 502** handle system call ioctl() 503** 504** returns: 505** 0 - okay 506** < 0 - error value 507*/ 508static int cowlo_ioctl(struct block_device *bdev, fmode_t mode, 509 unsigned int cmd, unsigned long arg) 510{ 511 struct hd_geometry geo; 512 struct inode *inode = bdev->bd_inode; 513 514 DEBUGP(DCOW "cowloop - ioctl cmd %x\n", cmd); 515 516 switch ( iminor(inode) ) { 517 518 /* 519 ** allowed via control device only 520 */ 521 case COWCTL: 522 switch (cmd) { 523 /* 524 ** write all bitmap chunks and cowheaders to cowfiles 525 */ 526 case COWSYNC: 527 down(&cowdevlock); 528 cowlo_sync(); 529 up(&cowdevlock); 530 return 0; 531 532 /* 533 ** open a new cowdevice (pair of rdofile/cowfile) 534 */ 535 case COWMKPAIR: 536 return cowlo_makepair((void __user *)arg); 537 538 /* 539 ** close a cowdevice (pair of rdofile/cowfile) 540 */ 541 case COWRMPAIR: 542 return cowlo_removepair((void __user *)arg); 543 544 /* 545 ** watch free space of filesystem containing cowfile 546 */ 547 case COWWATCH: 548 return cowlo_watch((void __user *)arg); 549 550 /* 551 ** close cowfile for active device 552 */ 553 case COWCLOSE: 554 return cowlo_cowctl((void __user *)arg, COWCLOSE); 555 556 /* 557 ** reopen cowfile read-only for active device 558 */ 559 case COWRDOPEN: 560 return cowlo_cowctl((void __user *)arg, COWRDOPEN); 561 562 default: 563 return -EINVAL; 564 } /* end of switch on command */ 565 566 /* 567 ** allowed for any other cowdevice 568 */ 569 default: 570 switch (cmd) { 571 /* 572 ** HDIO_GETGEO must be supported for fdisk, etc 573 */ 574 case HDIO_GETGEO: 575 geo.cylinders = 0; 576 geo.heads = 0; 577 geo.sectors = 0; 578 579 if (copy_to_user((void __user *)arg, &geo, sizeof geo)) 580 return -EFAULT; 581 return 0; 582 583 default: 584 return -EINVAL; 585 } /* end of switch on ioctl-cmd code parameter */ 586 } /* end of switch on minor number */ 587} 588 589static struct block_device_operations cowlo_fops = 590{ 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 */ 595}; 596 597/* 598** handle ioctl-command COWMKPAIR: 599** open a new cowdevice (pair of rdofile/cowfile) on-the-fly 600** 601** returns: 602** 0 - okay 603** < 0 - error value 604*/ 605static int 606cowlo_makepair(struct cowpair __user *arg) 607{ 608 int i, rv=0; 609 struct cowpair cowpair; 610 unsigned char *cowpath; 611 unsigned char *rdopath; 612 613 /* 614 ** retrieve info about pathnames 615 */ 616 if ( copy_from_user(&cowpair, arg, sizeof cowpair) ) 617 return -EFAULT; 618 619 if ( (MAJOR(cowpair.device) != COWMAJOR) && (cowpair.device != ANYDEV) ) 620 return -EINVAL; 621 622 if ( (MINOR(cowpair.device) >= maxcows) && (cowpair.device != ANYDEV) ) 623 return -EINVAL; 624 625 /* 626 ** retrieve pathname strings 627 */ 628 if ( (cowpair.cowflen > PATH_MAX) || (cowpair.rdoflen > PATH_MAX) ) 629 return -ENAMETOOLONG; 630 631 if ( !(cowpath = kmalloc(cowpair.cowflen+1, GFP_KERNEL)) ) 632 return -ENOMEM; 633 634 if ( copy_from_user(cowpath, (void __user *)cowpair.cowfile, 635 cowpair.cowflen) ) { 636 kfree(cowpath); 637 return -EFAULT; 638 } 639 *(cowpath+cowpair.cowflen) = 0; 640 641 if ( !(rdopath = kmalloc(cowpair.rdoflen+1, GFP_KERNEL)) ) { 642 kfree(cowpath); 643 return -ENOMEM; 644 } 645 646 if ( copy_from_user(rdopath, (void __user *)cowpair.rdofile, 647 cowpair.rdoflen) ) { 648 kfree(rdopath); 649 kfree(cowpath); 650 return -EFAULT; 651 } 652 *(rdopath+cowpair.rdoflen) = 0; 653 654 /* 655 ** open new cowdevice 656 */ 657 if ( cowpair.device == ANYDEV) { 658 /* 659 ** search first unused minor 660 */ 661 for (i=0, rv=-EBUSY; i < maxcows; i++) { 662 if ( !((cowdevall[i])->state & COWDEVOPEN) ) { 663 rv = cowlo_openpair(rdopath, cowpath, 0, i); 664 break; 665 } 666 } 667 668 if (rv) { /* open failed? */ 669 kfree(rdopath); 670 kfree(cowpath); 671 return rv; 672 } 673 674 /* 675 ** return newly allocated cowdevice to user space 676 */ 677 cowpair.device = MKDEV(COWMAJOR, i); 678 679 if ( copy_to_user(arg, &cowpair, sizeof cowpair)) { 680 kfree(rdopath); 681 kfree(cowpath); 682 return -EFAULT; 683 } 684 } else { /* specific minor requested */ 685 if ( (rv = cowlo_openpair(rdopath, cowpath, 0, 686 MINOR(cowpair.device)))) { 687 kfree(rdopath); 688 kfree(cowpath); 689 return rv; 690 } 691 } 692 693 return 0; 694} 695 696/* 697** handle ioctl-command COWRMPAIR: 698** deactivate an existing cowdevice (pair of rdofile/cowfile) on-the-fly 699** 700** returns: 701** 0 - okay 702** < 0 - error value 703*/ 704static int 705cowlo_removepair(unsigned long __user *arg) 706{ 707 unsigned long cowdevice; 708 struct cowloop_device *cowdev; 709 710 /* 711 ** retrieve info about device to be removed 712 */ 713 if ( copy_from_user(&cowdevice, arg, sizeof cowdevice)) 714 return -EFAULT; 715 716 /* 717 ** verify major-minor number 718 */ 719 if ( MAJOR(cowdevice) != COWMAJOR) 720 return -EINVAL; 721 722 if ( MINOR(cowdevice) >= maxcows) 723 return -EINVAL; 724 725 cowdev = cowdevall[MINOR(cowdevice)]; 726 727 if ( !(cowdev->state & COWDEVOPEN) ) 728 return -ENODEV; 729 730 /* 731 ** synchronize bitmaps and close cowdevice 732 */ 733 if (cowdev->state & COWRWCOWOPEN) { 734 down(&cowdevlock); 735 cowlo_sync(); 736 up(&cowdevlock); 737 } 738 739 return cowlo_closepair(cowdev); 740} 741 742/* 743** handle ioctl-command COWWATCH: 744** watch the free space of the filesystem containing a cowfile 745** of an open cowdevice 746** 747** returns: 748** 0 - okay 749** < 0 - error value 750*/ 751static int 752cowlo_watch(struct cowpair __user *arg) 753{ 754 struct cowloop_device *cowdev; 755 struct cowwatch cowwatch; 756 757 /* 758 ** retrieve structure holding info 759 */ 760 if ( copy_from_user(&cowwatch, arg, sizeof cowwatch)) 761 return -EFAULT; 762 763 /* 764 ** verify if cowdevice exists and is currently open 765 */ 766 if ( MINOR(cowwatch.device) >= maxcows) 767 return -EINVAL; 768 769 cowdev = cowdevall[MINOR(cowwatch.device)]; 770 771 if ( !(cowdev->state & COWDEVOPEN) ) 772 return -ENODEV; 773 774 /* 775 ** if the WATCHWAIT-option is set, wait until the indicated 776 ** threshold is reached (only one waiter allowed) 777 */ 778 if (cowwatch.flags & WATCHWAIT) { 779 /* 780 ** check if already another waiter active 781 ** for this cowdevice 782 */ 783 if (cowdev->state & COWWATCHDOG) 784 return -EAGAIN; 785 786 cowdev->state |= COWWATCHDOG; 787 788 cowdev->watchthresh = (unsigned long long) 789 cowwatch.threshold / 790 (cowdev->blksize / 1024); 791 792 if (wait_event_interruptible(cowdev->watchq, 793 cowdev->watchthresh >= cowdev->blkavail)) { 794 cowdev->state &= ~COWWATCHDOG; 795 return EINTR; 796 } 797 798 cowdev->state &= ~COWWATCHDOG; 799 } 800 801 cowwatch.totalkb = (unsigned long long)cowdev->blktotal * 802 cowdev->blksize / 1024; 803 cowwatch.availkb = (unsigned long long)cowdev->blkavail * 804 cowdev->blksize / 1024; 805 806 if ( copy_to_user(arg, &cowwatch, sizeof cowwatch)) 807 return -EFAULT; 808 809 return 0; 810} 811 812/* 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 820** 821** returns: 822** 0 - okay 823** < 0 - error value 824*/ 825static int 826cowlo_cowctl(unsigned long __user *arg, int cmd) 827{ 828 struct cowloop_device *cowdev; 829 unsigned long cowdevice; 830 831 /* 832 ** retrieve info about device to be removed 833 */ 834 if ( copy_from_user(&cowdevice, arg, sizeof cowdevice)) 835 return -EFAULT; 836 837 /* 838 ** verify major-minor number 839 */ 840 if ( MAJOR(cowdevice) != COWMAJOR) 841 return -EINVAL; 842 843 if ( MINOR(cowdevice) >= maxcows) 844 return -EINVAL; 845 846 cowdev = cowdevall[MINOR(cowdevice)]; 847 848 if ( !(cowdev->state & COWDEVOPEN) ) 849 return -ENODEV; 850 851 /* 852 ** synchronize bitmaps and close cowfile 853 */ 854 if (cowdev->state & COWRWCOWOPEN) { 855 down(&cowdevlock); 856 cowlo_sync(); 857 up(&cowdevlock); 858 } 859 860 /* 861 ** handle specific ioctl-command 862 */ 863 switch (cmd) { 864 case COWRDOPEN: 865 /* 866 ** if the cowfile is still opened read-write 867 */ 868 if (cowdev->state & COWRWCOWOPEN) { 869 /* 870 ** close the cowfile 871 */ 872 if (cowdev->cowfp) 873 filp_close(cowdev->cowfp, 0); 874 875 cowdev->state &= ~COWRWCOWOPEN; 876 877 /* 878 ** open again for read-only 879 */ 880 cowdev->cowfp = filp_open(cowdev->cowname, 881 O_RDONLY|O_LARGEFILE, 0600); 882 883 if ( (cowdev->cowfp == NULL) || IS_ERR(cowdev->cowfp) ) { 884 printk(KERN_ERR 885 "cowloop - failed to reopen cowfile %s\n", 886 cowdev->cowname); 887 return -EINVAL; 888 } 889 890 /* 891 ** mark cowfile open for read-only 892 */ 893 cowdev->state |= COWRDCOWOPEN; 894 } else { 895 return -EINVAL; 896 } 897 break; 898 899 case COWCLOSE: 900 /* 901 ** if the cowfile is still open 902 */ 903 if (cowdev->state & COWCOWOPEN) { 904 /* 905 ** close the cowfile 906 */ 907 if (cowdev->cowfp) 908 filp_close(cowdev->cowfp, 0); 909 910 cowdev->state &= ~COWCOWOPEN; 911 } 912 } 913 914 return 0; 915} 916 917 918/*****************************************************************************/ 919/* Handling of I/O-requests for a cowdevice */ 920/*****************************************************************************/ 921 922/* 923** function to be called by core-kernel to handle the I/O-requests 924** in the queue 925*/ 926static void cowlo_request(struct request_queue *q) 927{ 928 struct request *req; 929 struct cowloop_device *cowdev; 930 931 DEBUGP(DCOW "cowloop - request function called....\n"); 932 933 while((req = blk_peek_request(q)) != NULL) { 934 DEBUGP(DCOW "cowloop - got next request\n"); 935 936 if (! blk_fs_request(req)) { 937 /* this is not a normal file system request */ 938 __blk_end_request_cur(req, -EIO); 939 continue; 940 } 941 cowdev = req->rq_disk->private_data; 942 943 if (cowdev->iobusy) 944 return; 945 else 946 cowdev->iobusy = 1; 947 948 /* 949 ** when no kernel-thread is available, the request will 950 ** produce an I/O-error 951 */ 952 if (!cowdev->pid) { 953 printk(KERN_ERR"cowloop - no thread available\n"); 954 __blk_end_request_cur(req, -EIO); /* request failed */ 955 cowdev->iobusy = 0; 956 continue; 957 } 958 959 /* 960 ** handle I/O-request in the context of the kernel-thread 961 */ 962 cowdev->req = req; 963 cowdev->qfilled = 1; 964 965 wake_up_interruptible_sync(&cowdev->waitq); 966 967 /* 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 972 */ 973 return; 974 } 975} 976 977/* 978** daemon-process (kernel-thread) executes this function 979*/ 980static int 981cowlo_daemon(struct cowloop_device *cowdev) 982{ 983 int rv; 984 int minor; 985 char myname[16]; 986 987 for (minor = 0; minor < maxcows; minor++) { 988 if (cowdev == cowdevall[minor]) break; 989 } 990 sprintf(myname, "cowloopd%d", minor); 991 992 daemonize(myname); 993 994 while (!cowdev->closedown) { 995 /* 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) 1000 */ 1001 if (wait_event_interruptible(cowdev->waitq, cowdev->qfilled)){ 1002 flush_signals(current); /* ignore signal-based wakeup */ 1003 continue; 1004 } 1005 1006 if (cowdev->closedown) /* module will be unloaded ? */{ 1007 cowdev->pid = 0; 1008 return 0; 1009 } 1010 1011 /* 1012 ** woken up by the I/O-request handler: treat requested I/O 1013 */ 1014 cowdev->qfilled = 0; 1015 1016 rv = cowlo_do_request(cowdev->req); 1017 1018 /* 1019 ** reacquire the queue-spinlock for manipulating 1020 ** the request-queue and dequeue the request 1021 */ 1022 spin_lock_irq(&cowdev->rqlock); 1023 1024 __blk_end_request_cur(cowdev->req, rv); 1025 cowdev->iobusy = 0; 1026 1027 /* 1028 ** initiate the next request from the queue 1029 */ 1030 cowlo_request(cowdev->rqueue); 1031 1032 spin_unlock_irq(&cowdev->rqlock); 1033 } 1034 return 0; 1035} 1036 1037/* 1038** function to be called in the context of the kernel thread 1039** to handle the queued I/O-requests 1040** 1041** returns: 1042** 0 - fail 1043** 1 - success 1044*/ 1045static long int 1046cowlo_do_request(struct request *req) 1047{ 1048 unsigned long len; 1049 long int rv; 1050 loff_t offset; 1051 struct cowloop_device *cowdev = req->rq_disk->private_data; 1052 1053 /* 1054 ** calculate some variables which are needed later on 1055 */ 1056 len = blk_rq_cur_sectors(req) << 9; 1057 offset = (loff_t) blk_rq_pos(req) << 9; 1058 1059 DEBUGP(DCOW"cowloop - req cmd=%d offset=%lld len=%lu addr=%p\n", 1060 *(req->cmd), offset, len, req->buffer); 1061 1062 /* 1063 ** handle READ- or WRITE-request 1064 */ 1065 switch (rq_data_dir(req)) { 1066 /**********************************************************/ 1067 case READ: 1068 switch ( cowlo_checkio(cowdev, len, offset) ) { 1069 case ALLCOW: 1070 rv = cowlo_readcow(cowdev, req->buffer, len, offset); 1071 break; 1072 1073 case ALLRDO: 1074 rv = cowlo_readrdo(cowdev, req->buffer, len, offset); 1075 break; 1076 1077 case MIXEDUP: 1078 rv = cowlo_readmix(cowdev, req->buffer, len, offset); 1079 break; 1080 1081 default: 1082 rv = 0; /* never happens */ 1083 } 1084 break; 1085 1086 /**********************************************************/ 1087 case WRITE: 1088 switch ( cowlo_checkio(cowdev, len, offset) ) { 1089 case ALLCOW: 1090 /* 1091 ** straight-forward write will do... 1092 */ 1093 DEBUGP(DCOW"cowloop - write straight "); 1094 1095 rv = cowlo_writecow(cowdev, req->buffer, len, offset); 1096 break; /* from switch */ 1097 1098 case ALLRDO: 1099 if ( (len & MUMASK) == 0) { 1100 DEBUGP(DCOW"cowloop - write straight "); 1101 1102 rv = cowlo_writecow(cowdev, req->buffer, 1103 len, offset); 1104 break; 1105 } 1106 1107 case MIXEDUP: 1108 rv = cowlo_writemix(cowdev, req->buffer, len, offset); 1109 break; 1110 1111 default: 1112 rv = 0; /* never happens */ 1113 } 1114 break; 1115 1116 default: 1117 printk(KERN_ERR 1118 "cowloop - unrecognized command %d\n", *(req->cmd)); 1119 rv = 0; 1120 } 1121 1122 return (rv <= 0 ? 0 : 1); 1123} 1124 1125/* 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) 1129** 1130** returns: 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 1134*/ 1135static int 1136cowlo_checkio(struct cowloop_device *cowdev, int len, loff_t offset) 1137{ 1138 unsigned long mapnum, bytenum, bitnum, blocknr, partlen; 1139 long int totcnt, cowcnt; 1140 char *mc; 1141 1142 /* 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 1148 */ 1149 if ( (len <= MAPUNIT) && 1150 (MAPUNIT - (offset & MUMASK) <= len) ) { 1151 /* 1152 ** easy situation: 1153 ** requested data-block entirely fits within 1154 ** the mapunit used for the bitmap 1155 ** check if that block is located in rdofile or 1156 ** cowfile 1157 */ 1158 blocknr = offset >> MUSHIFT; 1159 1160 mapnum = CALCMAP (blocknr); 1161 bytenum = CALCBYTE(blocknr); 1162 bitnum = CALCBIT (blocknr); 1163 1164 if (*(*(cowdev->mapcache+mapnum)+bytenum)&(1<<bitnum)) 1165 return ALLCOW; 1166 else 1167 return ALLRDO; 1168 } 1169 1170 /* 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) 1176 */ 1177 for (cowcnt=totcnt=0; len > 0; len-=partlen, offset+=partlen, totcnt++){ 1178 /* 1179 ** calculate blocknr of involved block 1180 */ 1181 blocknr = offset >> MUSHIFT; 1182 1183 /* 1184 ** calculate partial length for this transfer 1185 */ 1186 partlen = MAPUNIT - (offset & MUMASK); 1187 if (partlen > len) 1188 partlen = len; 1189 1190 /* 1191 ** is this block located in the cowfile 1192 */ 1193 mapnum = CALCMAP (blocknr); 1194 bytenum = CALCBYTE(blocknr); 1195 bitnum = CALCBIT (blocknr); 1196 1197 mc = *(cowdev->mapcache+mapnum); 1198 1199 if (*(mc+bytenum)&(1<<bitnum)) 1200 cowcnt++;; 1201 1202 DEBUGP(DCOW 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, 1206 *(mc+bytenum), mc); 1207 } 1208 1209 if (cowcnt == 0) /* all involved blocks on rdofile? */ 1210 return ALLRDO; 1211 1212 if (cowcnt == totcnt) /* all involved blocks on cowfile? */ 1213 return ALLCOW; 1214 1215 /* 1216 ** situation somewhat more complicated: 1217 ** involved underlying blocks spread over both files 1218 */ 1219 return MIXEDUP; 1220} 1221 1222/* 1223** read requested chunk partly from rdofile and partly from cowfile 1224** 1225** returns: 1226** 0 - fail 1227** 1 - success 1228*/ 1229static int 1230cowlo_readmix(struct cowloop_device *cowdev, void *buf, int len, loff_t offset) 1231{ 1232 unsigned long mapnum, bytenum, bitnum, blocknr, partlen; 1233 long int rv; 1234 char *mc; 1235 1236 /* 1237 ** complicated approach: breakup required of read-request 1238 */ 1239 for (rv=1; len > 0; len-=partlen, buf+=partlen, offset+=partlen) { 1240 /* 1241 ** calculate blocknr of entire block 1242 */ 1243 blocknr = offset >> MUSHIFT; 1244 1245 /* 1246 ** calculate partial length for this transfer 1247 */ 1248 partlen = MAPUNIT - (offset & MUMASK); 1249 if (partlen > len) 1250 partlen = len; 1251 1252 /* 1253 ** is this block located in the cowfile 1254 */ 1255 mapnum = CALCMAP (blocknr); 1256 bytenum = CALCBYTE(blocknr); 1257 bitnum = CALCBIT (blocknr); 1258 mc = *(cowdev->mapcache+mapnum); 1259 1260 if (*(mc+bytenum)&(1<<bitnum)) { 1261 /* 1262 ** read (partial) block from cowfile 1263 */ 1264 DEBUGP(DCOW"cowloop - split read " 1265 "cow partlen=%ld off=%lld\n", partlen, offset); 1266 1267 if (cowlo_readcow(cowdev, buf, partlen, offset) <= 0) 1268 rv = 0; 1269 } else { 1270 /* 1271 ** read (partial) block from rdofile 1272 */ 1273 DEBUGP(DCOW"cowloop - split read " 1274 "rdo partlen=%ld off=%lld\n", partlen, offset); 1275 1276 if (cowlo_readrdo(cowdev, buf, partlen, offset) <= 0) 1277 rv = 0; 1278 } 1279 } 1280 1281 return rv; 1282} 1283 1284/* 1285** chunk to be written to the cowfile needs pieces to be 1286** read from the rdofile 1287** 1288** returns: 1289** 0 - fail 1290** 1 - success 1291*/ 1292static int 1293cowlo_writemix(struct cowloop_device *cowdev, void *buf, int len, loff_t offset) 1294{ 1295 unsigned long mapnum, bytenum, bitnum, blocknr, partlen; 1296 long int rv; 1297 char *mc; 1298 1299 /* 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 1307 */ 1308 for (rv=1; len > 0; len-=partlen, buf+=partlen, offset+=partlen) { 1309 /* 1310 ** calculate partial length for this transfer 1311 */ 1312 partlen = MAPUNIT - (offset & MUMASK); 1313 if (partlen > len) 1314 partlen = len; 1315 1316 /* 1317 ** calculate blocknr of entire block 1318 */ 1319 blocknr = offset >> MUSHIFT; 1320 1321 /* 1322 ** has this block been written before? 1323 */ 1324 mapnum = CALCMAP (blocknr); 1325 bytenum = CALCBYTE(blocknr); 1326 bitnum = CALCBIT (blocknr); 1327 mc = *(cowdev->mapcache+mapnum); 1328 1329 if (*(mc+bytenum)&(1<<bitnum)) { 1330 /* 1331 ** block has been written before; 1332 ** write transparantly to cowfile 1333 */ 1334 DEBUGP(DCOW 1335 "cowloop - splitwr transp\n"); 1336 1337 if (cowlo_writecow(cowdev, buf, partlen, offset) <= 0) 1338 rv = 0; 1339 } else { 1340 /* 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 1345 ** be written 1346 */ 1347 if (partlen < MAPUNIT) { 1348 if (cowlo_readrdo(cowdev, cowdev->iobuf, 1349 MAPUNIT, (loff_t)blocknr << MUSHIFT) <= 0) 1350 rv = 0; 1351 } 1352 1353 /* 1354 ** transfer modified part into 1355 ** the block just read 1356 */ 1357 memcpy(cowdev->iobuf + (offset & MUMASK), buf, partlen); 1358 1359 /* 1360 ** write entire block to cowfile 1361 */ 1362 DEBUGP(DCOW"cowloop - split " 1363 "partlen=%ld off=%lld\n", 1364 partlen, (loff_t)blocknr << MUSHIFT); 1365 1366 if (cowlo_writecow(cowdev, cowdev->iobuf, MAPUNIT, 1367 (loff_t)blocknr << MUSHIFT) <= 0) 1368 rv = 0; 1369 } 1370 } 1371 1372 return rv; 1373} 1374 1375/*****************************************************************************/ 1376/* I/O-support for read-only file and copy-on-write file */ 1377/*****************************************************************************/ 1378 1379/* 1380** read data from the read-only file 1381** 1382** return-value: similar to user-mode read 1383*/ 1384static long int 1385cowlo_readrdo(struct cowloop_device *cowdev, void *buf, int len, loff_t offset) 1386{ 1387 long int rv; 1388 mm_segment_t old_fs; 1389 loff_t saveoffset = offset; 1390 1391 DEBUGP(DCOW"cowloop - readrdo called\n"); 1392 1393 old_fs = get_fs(); 1394 set_fs( get_ds() ); 1395 rv = cowdev->rdofp->f_op->read(cowdev->rdofp, buf, len, &offset); 1396 set_fs(old_fs); 1397 1398 if (rv < len) { 1399 printk(KERN_WARNING "cowloop - read-failure %ld on rdofile" 1400 "- offset=%lld len=%d\n", 1401 rv, saveoffset, len); 1402 } 1403 1404 cowdev->rdoreads++; 1405 return rv; 1406} 1407 1408/* 1409** read cowfile from a modified offset, i.e. skipping the bitmap and cowhead 1410** 1411** return-value: similar to user-mode read 1412*/ 1413static long int 1414cowlo_readcow(struct cowloop_device *cowdev, void *buf, int len, loff_t offset) 1415{ 1416 DEBUGP(DCOW"cowloop - readcow called\n"); 1417 1418 offset += cowdev->cowhead->doffset; 1419 1420 return cowlo_readcowraw(cowdev, buf, len, offset); 1421} 1422 1423/* 1424** read cowfile from an absolute offset 1425** 1426** return-value: similar to user-mode read 1427*/ 1428static long int 1429cowlo_readcowraw(struct cowloop_device *cowdev, 1430 void *buf, int len, loff_t offset) 1431{ 1432 long int rv; 1433 mm_segment_t old_fs; 1434 loff_t saveoffset = offset; 1435 1436 DEBUGP(DCOW"cowloop - readcowraw called\n"); 1437 1438 /* 1439 ** be sure that cowfile is opened for read-write 1440 */ 1441 if ( !(cowdev->state & COWCOWOPEN) ) { 1442 printk(KERN_WARNING 1443 "cowloop - read request from cowfile refused\n"); 1444 1445 return -EBADF; 1446 } 1447 1448 /* 1449 ** issue low level read 1450 */ 1451 old_fs = get_fs(); 1452 set_fs( get_ds() ); 1453 rv = cowdev->cowfp->f_op->read(cowdev->cowfp, buf, len, &offset); 1454 set_fs(old_fs); 1455 1456 if (rv < len) { 1457 printk(KERN_WARNING 1458 "cowloop - read-failure %ld on cowfile" 1459 "- offset=%lld len=%d\n", rv, saveoffset, len); 1460 } 1461 1462 cowdev->cowreads++; 1463 return rv; 1464} 1465 1466/* 1467** write cowfile from a modified offset, i.e. skipping the bitmap and cowhead 1468** 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 1471** 1472** return-value: similar to user-mode write 1473*/ 1474static long int 1475cowlo_writecow(struct cowloop_device *cowdev, void *buf, int len, loff_t offset) 1476{ 1477 long int rv; 1478 unsigned long mapnum=0, mapbyte=0, mapbit=0, cowblock=0, partlen; 1479 char *tmpptr, *mapptr = NULL; 1480 loff_t tmpoffset, mapoffset = 0; 1481 1482 DEBUGP(DCOW"cowloop - writecow called\n"); 1483 1484 /* 1485 ** be sure that cowfile is opened for read-write 1486 */ 1487 if ( !(cowdev->state & COWRWCOWOPEN) ) { 1488 printk(KERN_WARNING 1489 "cowloop - Write request to cowfile refused\n"); 1490 1491 return -EBADF; 1492 } 1493 1494 /* 1495 ** write the entire block to the cowfile 1496 */ 1497 tmpoffset = offset + cowdev->cowhead->doffset; 1498 1499 rv = cowlo_writecowraw(cowdev, buf, len, tmpoffset); 1500 1501 /* 1502 ** verify if enough space available on filesystem holding 1503 ** the cowfile 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 1508 */ 1509 if ( (rv <= 0) || 1510 (cowdev->state & COWWATCHDOG) || 1511 (cowdev->blkavail / 2 < SPCDFLINTVL) || 1512 (cowdev->cowwrites % SPCDFLINTVL == 0) ) { 1513 struct kstatfs ks; 1514 1515 if (vfs_statfs(cowdev->cowfp->f_dentry, &ks)==0){ 1516 if (ks.f_bavail <= SPCMINBLK) { 1517 switch (ks.f_bavail) { 1518 case 0: 1519 case 1: 1520 case 2: 1521 case 3: 1522 printk(KERN_ALERT 1523 "cowloop - " 1524 "ALERT: cowfile full!\n"); 1525 break; 1526 1527 default: 1528 printk(KERN_WARNING 1529 "cowloop - cowfile almost " 1530 "full (only %llu Kb free)\n", 1531 (unsigned long long) 1532 ks.f_bsize * ks.f_bavail /1024); 1533 } 1534 } 1535 1536 cowdev->blktotal = ks.f_blocks; 1537 cowdev->blkavail = ks.f_bavail; 1538 1539 /* 1540 ** wakeup watcher if threshold has been reached 1541 */ 1542 if ( (cowdev->state & COWWATCHDOG) && 1543 (cowdev->watchthresh >= cowdev->blkavail) ) { 1544 wake_up_interruptible(&cowdev->watchq); 1545 } 1546 } 1547 } 1548 1549 if (rv <= 0) 1550 return rv; 1551 1552 DEBUGP(DCOW"cowloop - block written\n"); 1553 1554 /* 1555 ** check if block(s) is/are written to the cowfile 1556 ** for the first time; if so, adapt the bitmap 1557 */ 1558 for (; len > 0; len-=partlen, offset+=partlen, buf+=partlen) { 1559 /* 1560 ** calculate partial length for this transfer 1561 */ 1562 partlen = MAPUNIT - (offset & MUMASK); 1563 if (partlen > len) 1564 partlen = len; 1565 1566 /* 1567 ** calculate bitnr of written chunk of cowblock 1568 */ 1569 cowblock = offset >> MUSHIFT; 1570 1571 mapnum = CALCMAP (cowblock); 1572 mapbyte = CALCBYTE(cowblock); 1573 mapbit = CALCBIT (cowblock); 1574 1575 if (*(*(cowdev->mapcache+mapnum)+mapbyte) & (1<<mapbit)) 1576 continue; /* already written before */ 1577 1578 /* 1579 ** if the block is written for the first time, 1580 ** the corresponding bit should be set in the bitmap 1581 */ 1582 *(*(cowdev->mapcache+mapnum)+mapbyte) |= (1<<mapbit); 1583 1584 cowdev->nrcowblocks++; 1585 1586 DEBUGP(DCOW"cowloop - bitupdate blk=%ld map=%ld " 1587 "byte=%ld bit=%ld\n", 1588 cowblock, mapnum, mapbyte, mapbit); 1589 1590 /* 1591 ** check if the cowhead in the cowfile is currently 1592 ** marked clean; if so, mark it dirty and flush it 1593 */ 1594 if ( !(cowdev->cowhead->flags &= COWDIRTY)) { 1595 cowdev->cowhead->flags |= COWDIRTY; 1596 1597 cowlo_writecowraw(cowdev, cowdev->cowhead, 1598 MAPUNIT, (loff_t)0); 1599 } 1600 1601 /* 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) 1607 */ 1608 if ( memcmp(buf, allzeroes, partlen) ) /* not all zeroes? */ 1609 continue; /* no flush needed */ 1610 1611 /* 1612 ** calculate positions of bitmap block to be flushed 1613 ** - pointer of bitmap block in memory 1614 ** - offset of bitmap block in cowfile 1615 */ 1616 tmpptr = *(cowdev->mapcache+mapnum) + (mapbyte & (~MUMASK)); 1617 tmpoffset = (loff_t) MAPUNIT + mapnum * MAPCHUNKSZ + 1618 (mapbyte & (~MUMASK)); 1619 1620 /* 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 1624 */ 1625 if ( (mapoffset != 0) && (mapoffset != tmpoffset) ) { 1626 if (cowlo_writecowraw(cowdev, mapptr, MAPUNIT, 1627 mapoffset) < 0) { 1628 printk(KERN_WARNING 1629 "cowloop - write-failure on bitmap - " 1630 "blk=%ld map=%ld byte=%ld bit=%ld\n", 1631 cowblock, mapnum, mapbyte, mapbit); 1632 } 1633 1634 DEBUGP(DCOW"cowloop - bitmap blk written %lld\n", 1635 mapoffset); 1636 } 1637 1638 /* 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 1642 ** been done 1643 */ 1644 mapoffset = tmpoffset; 1645 mapptr = tmpptr; 1646 } 1647 1648 /* 1649 ** any new block written containing binary zeroes? 1650 */ 1651 if (mapoffset) { 1652 if (cowlo_writecowraw(cowdev, mapptr, MAPUNIT, mapoffset) < 0) { 1653 printk(KERN_WARNING 1654 "cowloop - write-failure on bitmap - " 1655 "blk=%ld map=%ld byte=%ld bit=%ld\n", 1656 cowblock, mapnum, mapbyte, mapbit); 1657 } 1658 1659 DEBUGP(DCOW"cowloop - bitmap block written %lld\n", mapoffset); 1660 } 1661 1662 return rv; 1663} 1664 1665/* 1666** write cowfile from an absolute offset 1667** 1668** return-value: similar to user-mode write 1669*/ 1670static long int 1671cowlo_writecowraw(struct cowloop_device *cowdev, 1672 void *buf, int len, loff_t offset) 1673{ 1674 long int rv; 1675 mm_segment_t old_fs; 1676 loff_t saveoffset = offset; 1677 1678 DEBUGP(DCOW"cowloop - writecowraw called\n"); 1679 1680 /* 1681 ** be sure that cowfile is opened for read-write 1682 */ 1683 if ( !(cowdev->state & COWRWCOWOPEN) ) { 1684 printk(KERN_WARNING 1685 "cowloop - write request to cowfile refused\n"); 1686 1687 return -EBADF; 1688 } 1689 1690 /* 1691 ** issue low level write 1692 */ 1693 old_fs = get_fs(); 1694 set_fs( get_ds() ); 1695 rv = cowdev->cowfp->f_op->write(cowdev->cowfp, buf, len, &offset); 1696 set_fs(old_fs); 1697 1698 if (rv < len) { 1699 printk(KERN_WARNING 1700 "cowloop - write-failure %ld on cowfile" 1701 "- offset=%lld len=%d\n", rv, saveoffset, len); 1702 } 1703 1704 cowdev->cowwrites++; 1705 return rv; 1706} 1707 1708 1709/* 1710** readproc-function: called when the corresponding /proc-file is read 1711*/ 1712static int 1713cowlo_readproc(char *buf, char **start, off_t pos, int cnt, int *eof, void *p) 1714{ 1715 struct cowloop_device *cowdev = p; 1716 1717 revision[sizeof revision - 3] = '\0'; 1718 1719 return sprintf(buf, 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" 1730 " cowreads: %9lu\n" 1731 " cowwrites: %9lu\n", 1732 &revision[11], 1733 1734 cowdev->state & COWDEVOPEN ? "devopen " : "", 1735 cowdev->state & COWRWCOWOPEN ? "cowopenrw " : "", 1736 cowdev->state & COWRDCOWOPEN ? "cowopenro " : "", 1737 cowdev->state & COWWATCHDOG ? "watchdog " : "", 1738 1739 cowdev->opencnt, 1740 cowdev->pid, 1741 cowdev->rdoname, 1742 cowdev->rdoreads, 1743 cowdev->cowname, 1744 cowdev->cowhead->flags & COWDIRTY ? "dirty":"clean", 1745 cowdev->mapsize >> MUSHIFT, MAPUNIT, 1746 cowdev->nrcowblocks, MAPUNIT, 1747 cowdev->cowreads, 1748 cowdev->cowwrites); 1749} 1750 1751/*****************************************************************************/ 1752/* Setup and destroy cowdevices */ 1753/*****************************************************************************/ 1754 1755/* 1756** open and prepare a cowdevice (rdofile and cowfile) and allocate bitmaps 1757** 1758** returns: 1759** 0 - okay 1760** < 0 - error value 1761*/ 1762static int 1763cowlo_openpair(char *rdof, char *cowf, int autorecover, int minor) 1764{ 1765 long int rv; 1766 struct cowloop_device *cowdev = cowdevall[minor]; 1767 struct kstatfs ks; 1768 1769 down(&cowdevlock); 1770 1771 /* 1772 ** requested device exists? 1773 */ 1774 if (minor >= maxcows) { 1775 up(&cowdevlock); 1776 return -ENODEV; 1777 } 1778 1779 /* 1780 ** requested device already assigned to cowdevice? 1781 */ 1782 if (cowdev->state & COWDEVOPEN) { 1783 up(&cowdevlock); 1784 return -EBUSY; 1785 } 1786 1787 /* 1788 ** initialize administration 1789 */ 1790 memset(cowdev, 0, sizeof *cowdev); 1791 1792 spin_lock_init (&cowdev->rqlock); 1793 init_waitqueue_head(&cowdev->waitq); 1794 init_waitqueue_head(&cowdev->watchq); 1795 1796 /* 1797 ** open the read-only file 1798 */ 1799 DEBUGP(DCOW"cowloop - call openrdo....\n"); 1800 1801 if ( (rv = cowlo_openrdo(cowdev, rdof)) ) { 1802 cowlo_undo_openrdo(cowdev); 1803 up(&cowdevlock); 1804 return rv; 1805 } 1806 1807 /* 1808 ** open the cowfile 1809 */ 1810 DEBUGP(DCOW"cowloop - call opencow....\n"); 1811 1812 if ( (rv = cowlo_opencow(cowdev, cowf, autorecover)) ) { 1813 cowlo_undo_openrdo(cowdev); 1814 cowlo_undo_opencow(cowdev); 1815 up(&cowdevlock); 1816 return rv; 1817 } 1818 1819 /* 1820 ** administer total and available size of filesystem holding cowfile 1821 */ 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; 1826 } else { 1827 cowdev->blksize = 1024; /* avoid division by zero */ 1828 } 1829 1830 /* 1831 ** flush the (recovered) bitmaps and cowhead to the cowfile 1832 */ 1833 DEBUGP(DCOW"cowloop - call cowsync....\n"); 1834 1835 cowlo_sync(); 1836 1837 /* 1838 ** allocate gendisk for the cow device 1839 */ 1840 DEBUGP(DCOW"cowloop - alloc disk....\n"); 1841 1842 if ((cowdev->gd = alloc_disk(1)) == NULL) { 1843 printk(KERN_WARNING 1844 "cowloop - unable to alloc_disk for cowloop\n"); 1845 1846 cowlo_undo_openrdo(cowdev); 1847 cowlo_undo_opencow(cowdev); 1848 up(&cowdevlock); 1849 return -ENOMEM; 1850 } 1851 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); 1858 1859 /* in .5 Kb units */ 1860 set_capacity(cowdev->gd, (cowdev->numblocks*(MAPUNIT/512))); 1861 1862 DEBUGP(DCOW"cowloop - init request queue....\n"); 1863 1864 if ((cowdev->rqueue = blk_init_queue(cowlo_request, &cowdev->rqlock)) 1865 == NULL) { 1866 printk(KERN_WARNING 1867 "cowloop - unable to get request queue for cowloop\n"); 1868 1869 del_gendisk(cowdev->gd); 1870 cowlo_undo_openrdo(cowdev); 1871 cowlo_undo_opencow(cowdev); 1872 up(&cowdevlock); 1873 return -EINVAL; 1874 } 1875 1876 blk_queue_logical_block_size(cowdev->rqueue, cowdev->blocksz); 1877 cowdev->gd->queue = cowdev->rqueue; 1878 1879 /* 1880 ** start kernel thread to handle requests 1881 */ 1882 DEBUGP(DCOW"cowloop - kickoff daemon....\n"); 1883 1884 cowdev->pid = kernel_thread((int (*)(void *))cowlo_daemon, cowdev, 0); 1885 1886 /* 1887 ** create a file below directory /proc/cow for this new cowdevice 1888 */ 1889 if (cowlo_procdir) { 1890 char tmpname[64]; 1891 1892 sprintf(tmpname, "%d", minor); 1893 1894 create_proc_read_entry(tmpname, 0 , cowlo_procdir, 1895 cowlo_readproc, cowdev); 1896 } 1897 1898 cowdev->state |= COWDEVOPEN; 1899 1900 cowdev->rdoname = rdof; 1901 cowdev->cowname = cowf; 1902 1903 /* 1904 ** enable the new disk; this triggers the first request! 1905 */ 1906 DEBUGP(DCOW"cowloop - call add_disk....\n"); 1907 1908 add_disk(cowdev->gd); 1909 1910 up(&cowdevlock); 1911 return 0; 1912} 1913 1914/* 1915** close a cowdevice (pair of rdofile/cowfile) and release memory 1916** 1917** returns: 1918** 0 - okay 1919** < 0 - error value 1920*/ 1921static int 1922cowlo_closepair(struct cowloop_device *cowdev) 1923{ 1924 int minor; 1925 1926 down(&cowdevlock); 1927 1928 /* 1929 ** if cowdevice is not activated at all, refuse 1930 */ 1931 if ( !(cowdev->state & COWDEVOPEN) ) { 1932 up(&cowdevlock); 1933 return -ENODEV; 1934 } 1935 1936 /* 1937 ** if this cowdevice is still open, refuse 1938 */ 1939 if (cowdev->opencnt > 0) { 1940 up(&cowdevlock); 1941 return -EBUSY; 1942 } 1943 1944 up(&cowdevlock); 1945 1946 /* 1947 ** wakeup watcher (if any) 1948 */ 1949 if (cowdev->state & COWWATCHDOG) { 1950 cowdev->watchthresh = cowdev->blkavail; 1951 wake_up_interruptible(&cowdev->watchq); 1952 } 1953 1954 /* 1955 ** wakeup kernel-thread to be able to exit 1956 ** and wait until it has exited 1957 */ 1958 cowdev->closedown = 1; 1959 cowdev->qfilled = 1; 1960 wake_up_interruptible(&cowdev->waitq); 1961 1962 while (cowdev->pid) 1963 schedule(); 1964 1965 del_gendisk(cowdev->gd); /* revert the alloc_disk() */ 1966 put_disk(cowdev->gd); /* revert the add_disk() */ 1967 1968 if (cowlo_procdir) { 1969 char tmpname[64]; 1970 1971 for (minor = 0; minor < maxcows; minor++) { 1972 if (cowdev == cowdevall[minor]) break; 1973 } 1974 sprintf(tmpname, "%d", minor); 1975 1976 remove_proc_entry(tmpname, cowlo_procdir); 1977 } 1978 1979 blk_cleanup_queue(cowdev->rqueue); 1980 1981 /* 1982 ** release memory for filenames if these names have 1983 ** been allocated dynamically 1984 */ 1985 if ( (cowdev->cowname) && (cowdev->cowname != cowfile)) 1986 kfree(cowdev->cowname); 1987 1988 if ( (cowdev->rdoname) && (cowdev->rdoname != rdofile)) 1989 kfree(cowdev->rdoname); 1990 1991 cowlo_undo_openrdo(cowdev); 1992 cowlo_undo_opencow(cowdev); 1993 1994 cowdev->state &= ~COWDEVOPEN; 1995 1996 return 0; 1997} 1998 1999/* 2000** open the read-only file 2001** 2002** returns: 2003** 0 - okay 2004** < 0 - error value 2005*/ 2006static int 2007cowlo_openrdo(struct cowloop_device *cowdev, char *rdof) 2008{ 2009 struct file *f; 2010 struct inode *inode; 2011 long int i, nrval; 2012 2013 DEBUGP(DCOW"cowloop - openrdo called\n"); 2014 2015 /* 2016 ** open the read-only file 2017 */ 2018 if(*rdof == '\0') { 2019 printk(KERN_ERR 2020 "cowloop - specify name for read-only file\n\n"); 2021 return -EINVAL; 2022 } 2023 2024 f = filp_open(rdof, O_RDONLY|O_LARGEFILE, 0); 2025 2026 if ( (f == NULL) || IS_ERR(f) ) { 2027 printk(KERN_ERR 2028 "cowloop - open of rdofile %s failed\n", rdof); 2029 return -EINVAL; 2030 } 2031 2032 cowdev->rdofp = f; 2033 2034 inode = f->f_dentry->d_inode; 2035 2036 if ( !S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode) ) { 2037 printk(KERN_ERR 2038 "cowloop - %s not regular file or blockdev\n", rdof); 2039 return -EINVAL; 2040 } 2041 2042 DEBUGP(DCOW"cowloop - determine size rdo....\n"); 2043 2044 /* 2045 ** determine block-size and total size of read-only file 2046 */ 2047 if (S_ISREG(inode->i_mode)) { 2048 /* 2049 ** read-only file is a regular file 2050 */ 2051 cowdev->blocksz = 512; /* other value fails */ 2052 cowdev->numblocks = inode->i_size >> MUSHIFT; 2053 2054 if (inode->i_size & MUMASK) { 2055 printk(KERN_WARNING 2056 "cowloop - rdofile %s truncated to multiple " 2057 "of %d bytes\n", rdof, MAPUNIT); 2058 } 2059 2060 DEBUGP(DCOW"cowloop - RO=regular: numblocks=%d, blocksz=%d\n", 2061 cowdev->numblocks, cowdev->blocksz); 2062 } else { 2063 /* 2064 ** read-only file is a block device 2065 */ 2066 cowdev->belowdev = inode->i_bdev; 2067 cowdev->belowgd = cowdev->belowdev->bd_disk; /* gendisk */ 2068 2069 if (cowdev->belowdev->bd_part) { 2070 cowdev->numblocks = cowdev->belowdev->bd_part->nr_sects 2071 / (MAPUNIT/512); 2072 } 2073 2074 if (cowdev->belowgd) { 2075 cowdev->belowq = cowdev->belowgd->queue; 2076 2077 if (cowdev->numblocks == 0) { 2078 cowdev->numblocks = get_capacity(cowdev->belowgd) 2079 / (MAPUNIT/512); 2080 } 2081 } 2082 2083 2084 if (cowdev->belowq) 2085 cowdev->blocksz = queue_logical_block_size(cowdev->belowq); 2086 2087 if (cowdev->blocksz == 0) 2088 cowdev->blocksz = BLOCK_SIZE; /* default 2^10 */ 2089 2090 DEBUGP(DCOW"cowloop - numblocks=%d, " 2091 "blocksz=%d, belowgd=%p, belowq=%p\n", 2092 cowdev->numblocks, cowdev->blocksz, 2093 cowdev->belowgd, cowdev->belowq); 2094 2095 DEBUGP(DCOW"cowloop - belowdev.bd_block_size=%d\n", 2096 cowdev->belowdev->bd_block_size); 2097 } 2098 2099 if (cowdev->numblocks == 0) { 2100 printk(KERN_ERR "cowloop - %s has no contents\n", rdof); 2101 return -EINVAL; 2102 } 2103 2104 /* 2105 ** reserve space in memory as generic I/O buffer 2106 */ 2107 cowdev->iobuf = kmalloc(MAPUNIT, GFP_KERNEL); 2108 2109 if (!cowdev->iobuf) { 2110 printk(KERN_ERR 2111 "cowloop - cannot get space for buffer %d\n", MAPUNIT); 2112 return -ENOMEM; 2113 } 2114 2115 DEBUGP(DCOW"cowloop - determine fingerprint rdo....\n"); 2116 2117 /* 2118 ** determine fingerprint for read-only file 2119 ** calculate fingerprint from first four datablocks 2120 ** which do not contain binary zeroes 2121 */ 2122 for (i=0, cowdev->fingerprint=0, nrval=0; 2123 (nrval < 4)&&(i < cowdev->numblocks); i++) { 2124 int j; 2125 unsigned char cs; 2126 2127 /* 2128 ** read next block 2129 */ 2130 if (cowlo_readrdo(cowdev, cowdev->iobuf, MAPUNIT, 2131 (loff_t)i << MUSHIFT) < 1) 2132 break; 2133 2134 /* 2135 ** calculate fingerprint by adding all byte-values 2136 */ 2137 for (j=0, cs=0; j < MAPUNIT; j++) 2138 cs += *(cowdev->iobuf+j); 2139 2140 if (cs == 0) /* block probably contained zeroes */ 2141 continue; 2142 2143 /* 2144 ** shift byte-value to proper place in final fingerprint 2145 */ 2146 cowdev->fingerprint |= cs << (nrval*8); 2147 nrval++; 2148 } 2149 2150 return 0; 2151} 2152 2153/* 2154** undo memory allocs and file opens issued so far 2155** related to the read-only file 2156*/ 2157static void 2158cowlo_undo_openrdo(struct cowloop_device *cowdev) 2159{ 2160 if(cowdev->iobuf); 2161 kfree(cowdev->iobuf); 2162 2163 if (cowdev->rdofp) 2164 filp_close(cowdev->rdofp, 0); 2165} 2166 2167/* 2168** open the cowfile 2169** 2170** returns: 2171** 0 - okay 2172** < 0 - error value 2173*/ 2174static int 2175cowlo_opencow(struct cowloop_device *cowdev, char *cowf, int autorecover) 2176{ 2177 long int i, rv; 2178 int minor; 2179 unsigned long nb; 2180 struct file *f; 2181 struct inode *inode; 2182 loff_t offset; 2183 struct cowloop_device *cowtmp; 2184 2185 DEBUGP(DCOW"cowloop - opencow called\n"); 2186 2187 /* 2188 ** open copy-on-write file (read-write) 2189 */ 2190 if (cowf[0] == '\0') { 2191 printk(KERN_ERR 2192 "cowloop - specify name of copy-on-write file\n\n"); 2193 return -EINVAL; 2194 } 2195 2196 f = filp_open(cowf, O_RDWR|O_LARGEFILE, 0600); 2197 2198 if ( (f == NULL) || IS_ERR(f) ) { 2199 /* 2200 ** non-existing cowfile: try to create 2201 */ 2202 f = filp_open(cowf, O_RDWR|O_CREAT|O_LARGEFILE, 0600); 2203 2204 if ( (f == NULL) || IS_ERR(f) ) { 2205 printk(KERN_ERR 2206 "cowloop - failed to open file %s for read-write\n\n", 2207 cowf); 2208 return -EINVAL; 2209 } 2210 } 2211 2212 cowdev->cowfp = f; 2213 2214 inode = f->f_dentry->d_inode; 2215 2216 if (!S_ISREG(inode->i_mode)) { 2217 printk(KERN_ERR "cowloop - %s is not regular file\n", cowf); 2218 return -EINVAL; 2219 } 2220 2221 /* 2222 ** check if this cowfile is already in use for another cowdevice 2223 */ 2224 for (minor = 0; minor < maxcows; minor++) { 2225 2226 cowtmp = cowdevall[minor]; 2227 2228 if ( !(cowtmp->state & COWDEVOPEN) ) 2229 continue; 2230 2231 if (cowtmp == cowdev) 2232 continue; 2233 2234 if (cowtmp->cowfp->f_dentry->d_inode == f->f_dentry->d_inode) { 2235 printk(KERN_ERR 2236 "cowloop - %s: already in use as cow\n", cowf); 2237 return -EBUSY; 2238 } 2239 } 2240 2241 /* 2242 ** mark cowfile open for read-write 2243 */ 2244 cowdev->state |= COWRWCOWOPEN; 2245 2246 /* 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 2250 */ 2251 nb = cowdev->numblocks; 2252 2253 if (nb%8) /* transform #bits to #bytes */ 2254 nb+=8; /* rounded if necessary */ 2255 nb /= 8; 2256 2257 if (nb & MUMASK) /* round up #bytes to MAPUNIT chunks */ 2258 cowdev->mapsize = ( (nb>>MUSHIFT) +1) << MUSHIFT; 2259 else 2260 cowdev->mapsize = nb; 2261 2262 /* 2263 ** reserve space in memory for the cowhead 2264 */ 2265 cowdev->cowhead = kmalloc(MAPUNIT, GFP_KERNEL); 2266 2267 if (!cowdev->cowhead) { 2268 printk(KERN_ERR "cowloop - cannot get space for cowhead %d\n", 2269 MAPUNIT); 2270 return -ENOMEM; 2271 } 2272 2273 memset(cowdev->cowhead, 0, MAPUNIT); 2274 2275 DEBUGP(DCOW"cowloop - prepare cowhead....\n"); 2276 2277 /* 2278 ** check if the cowfile exists or should be created 2279 */ 2280 if (inode->i_size != 0) { 2281 /* 2282 ** existing cowfile: read the cow head 2283 */ 2284 if (inode->i_size < MAPUNIT) { 2285 printk(KERN_ERR 2286 "cowloop - existing cowfile %s too small\n", 2287 cowf); 2288 return -EINVAL; 2289 } 2290 2291 cowlo_readcowraw(cowdev, cowdev->cowhead, MAPUNIT, (loff_t) 0); 2292 2293 /* 2294 ** verify if the existing file is really a cowfile 2295 */ 2296 if (cowdev->cowhead->magic != COWMAGIC) { 2297 printk(KERN_ERR 2298 "cowloop - cowfile %s has incorrect format\n", 2299 cowf); 2300 return -EINVAL; 2301 } 2302 2303 /* 2304 ** verify the cowhead version of the cowfile 2305 */ 2306 if (cowdev->cowhead->version > COWVERSION) { 2307 printk(KERN_ERR 2308 "cowloop - cowfile %s newer than this driver\n", 2309 cowf); 2310 return -EINVAL; 2311 } 2312 2313 /* 2314 ** make sure that this is not a packed cowfile 2315 */ 2316 if (cowdev->cowhead->flags & COWPACKED) { 2317 printk(KERN_ERR 2318 "cowloop - packed cowfile %s not accepted\n", cowf); 2319 return -EINVAL; 2320 } 2321 2322 /* 2323 ** verify if the cowfile has been properly closed 2324 */ 2325 if (cowdev->cowhead->flags & COWDIRTY) { 2326 /* 2327 ** cowfile was not properly closed; 2328 ** check if automatic recovery is required 2329 ** (actual recovery will be done later on) 2330 */ 2331 if (!autorecover) { 2332 printk(KERN_ERR 2333 "cowloop - cowfile %s is dirty " 2334 "(not properly closed by rmmod?)\n", 2335 cowf); 2336 printk(KERN_ERR 2337 "cowloop - run cowrepair or specify " 2338 "'option=r' to recover\n"); 2339 return -EINVAL; 2340 } 2341 } 2342 2343 /* 2344 ** verify if the cowfile is really related to this rdofile 2345 */ 2346 if (cowdev->cowhead->rdoblocks != cowdev->numblocks) { 2347 printk(KERN_ERR 2348 "cowloop - cowfile %s (size %lld) not related " 2349 "to rdofile (size %lld)\n", 2350 cowf, 2351 (long long)cowdev->cowhead->rdoblocks <<MUSHIFT, 2352 (long long)cowdev->numblocks <<MUSHIFT); 2353 return -EINVAL; 2354 } 2355 2356 if (cowdev->cowhead->rdofingerprint != cowdev->fingerprint) { 2357 printk(KERN_ERR 2358 "cowloop - cowfile %s not related to rdofile " 2359 " (fingerprint err - rdofile modified?)\n", cowf); 2360 return -EINVAL; 2361 } 2362 } else { 2363 /* 2364 ** new cowfile: determine the minimal size (cowhead+bitmap) 2365 */ 2366 offset = (loff_t) MAPUNIT + cowdev->mapsize - 1; 2367 2368 if ( cowlo_writecowraw(cowdev, "", 1, offset) < 1) { 2369 printk(KERN_ERR 2370 "cowloop - cannot set cowfile to size %lld\n", 2371 offset+1); 2372 return -EINVAL; 2373 } 2374 2375 /* 2376 ** prepare new cowhead 2377 */ 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; 2385 2386 /* 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 2391 */ 2392 cowdev->cowhead->doffset = 2393 ((MAPUNIT+cowdev->mapsize+4095)>>12)<<12; 2394 } 2395 2396 cowdev->cowhead->flags = 0; 2397 2398 DEBUGP(DCOW"cowloop - reserve space bitmap....\n"); 2399 2400 /* 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 2405 */ 2406 cowdev->mapcount = (cowdev->mapsize+MAPCHUNKSZ-1)/MAPCHUNKSZ; 2407 2408 /* 2409 ** the size of every bitmap chunk will be MAPCHUNKSZ bytes, except for 2410 ** the last bitmap chunk: calculate remaining size for this chunk 2411 */ 2412 if (cowdev->mapsize % MAPCHUNKSZ == 0) 2413 cowdev->mapremain = MAPCHUNKSZ; 2414 else 2415 cowdev->mapremain = cowdev->mapsize % MAPCHUNKSZ; 2416 2417 /* 2418 ** allocate space to store all pointers for the bitmap-chunks 2419 ** (initialize area with zeroes to allow proper undo) 2420 */ 2421 cowdev->mapcache = kmalloc(cowdev->mapcount * sizeof(char *), 2422 GFP_KERNEL); 2423 if (!cowdev->mapcache) { 2424 printk(KERN_ERR 2425 "cowloop - can not allocate space for bitmap ptrs\n"); 2426 return -ENOMEM; 2427 } 2428 2429 memset(cowdev->mapcache, 0, cowdev->mapcount * sizeof(char *)); 2430 2431 /* 2432 ** allocate space to store the bitmap-chunks themselves 2433 */ 2434 for (i=0; i < cowdev->mapcount; i++) { 2435 if (i < (cowdev->mapcount-1)) 2436 *(cowdev->mapcache+i) = kmalloc(MAPCHUNKSZ, GFP_KERNEL); 2437 else 2438 *(cowdev->mapcache+i) = kmalloc(cowdev->mapremain, 2439 GFP_KERNEL); 2440 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, 2445 MAPUNIT); 2446 return -ENOMEM; 2447 } 2448 } 2449 2450 DEBUGP(DCOW"cowloop - read bitmap from cow....\n"); 2451 2452 /* 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) 2456 */ 2457 for (i=0, offset=MAPUNIT; i < cowdev->mapcount; 2458 i++, offset+=MAPCHUNKSZ) { 2459 unsigned long numbytes; 2460 2461 if (i < (cowdev->mapcount-1)) 2462 /* 2463 ** full bitmap chunk 2464 */ 2465 numbytes = MAPCHUNKSZ; 2466 else 2467 /* 2468 ** last bitmap chunk: might be partly filled 2469 */ 2470 numbytes = cowdev->mapremain; 2471 2472 cowlo_readcowraw(cowdev, *(cowdev->mapcache+i), 2473 numbytes, offset); 2474 } 2475 2476 /* 2477 ** if the cowfile was dirty and automatic recovery is required, 2478 ** reconstruct a proper bitmap in memory now 2479 */ 2480 if (cowdev->cowhead->flags & COWDIRTY) { 2481 unsigned long long blocknum; 2482 char databuf[MAPUNIT]; 2483 unsigned long mapnum, mapbyte, mapbit; 2484 2485 printk(KERN_NOTICE "cowloop - recover dirty cowfile %s....\n", 2486 cowf); 2487 2488 /* 2489 ** read all data blocks 2490 */ 2491 for (blocknum=0, rv=1, offset=0; 2492 cowlo_readcow(cowdev, databuf, MAPUNIT, offset) > 0; 2493 blocknum++, offset += MAPUNIT) { 2494 2495 /* 2496 ** if this datablock contains real data (not binary 2497 ** zeroes), set the corresponding bit in the bitmap 2498 */ 2499 if ( memcmp(databuf, allzeroes, MAPUNIT) == 0) 2500 continue; 2501 2502 mapnum = CALCMAP (blocknum); 2503 mapbyte = CALCBYTE(blocknum); 2504 mapbit = CALCBIT (blocknum); 2505 2506 *(*(cowdev->mapcache+mapnum)+mapbyte) |= (1<<mapbit); 2507 } 2508 2509 printk(KERN_NOTICE "cowloop - cowfile recovery completed\n"); 2510 } 2511 2512 /* 2513 ** count all bits set in the bitmaps for statistical purposes 2514 */ 2515 for (i=0, cowdev->nrcowblocks = 0; i < cowdev->mapcount; i++) { 2516 long numbytes; 2517 char *p; 2518 2519 if (i < (cowdev->mapcount-1)) 2520 numbytes = MAPCHUNKSZ; 2521 else 2522 numbytes = cowdev->mapremain; 2523 2524 p = *(cowdev->mapcache+i); 2525 2526 for (numbytes--; numbytes >= 0; numbytes--, p++) { 2527 /* 2528 ** for only eight checks the following construction 2529 ** is faster than a loop-construction 2530 */ 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++; 2539 } 2540 } 2541 2542 /* 2543 ** consistency-check for number of bits set in bitmap 2544 */ 2545 if ( !(cowdev->cowhead->flags & COWDIRTY) && 2546 (cowdev->cowhead->cowused != cowdev->nrcowblocks) ) { 2547 printk(KERN_ERR "cowloop - inconsistent cowfile admi\n"); 2548 return -EINVAL; 2549 } 2550 2551 return 0; 2552} 2553 2554/* 2555** undo memory allocs and file opens issued so far 2556** related to the cowfile 2557*/ 2558static void 2559cowlo_undo_opencow(struct cowloop_device *cowdev) 2560{ 2561 int i; 2562 2563 if (cowdev->mapcache) { 2564 for (i=0; i < cowdev->mapcount; i++) { 2565 if (*(cowdev->mapcache+i) != NULL) 2566 kfree( *(cowdev->mapcache+i) ); 2567 } 2568 2569 kfree(cowdev->mapcache); 2570 } 2571 2572 if (cowdev->cowhead) 2573 kfree(cowdev->cowhead); 2574 2575 if ( (cowdev->state & COWCOWOPEN) && (cowdev->cowfp) ) 2576 filp_close(cowdev->cowfp, 0); 2577 2578 /* 2579 ** mark cowfile closed 2580 */ 2581 cowdev->state &= ~COWCOWOPEN; 2582} 2583 2584/* 2585** flush the entire bitmap and the cowhead (clean) to the cowfile 2586** 2587** must be called with the cowdevices-lock set 2588*/ 2589static void 2590cowlo_sync(void) 2591{ 2592 int i, minor; 2593 loff_t offset; 2594 struct cowloop_device *cowdev; 2595 2596 for (minor=0; minor < maxcows; minor++) { 2597 cowdev = cowdevall[minor]; 2598 if ( ! (cowdev->state & COWRWCOWOPEN) ) 2599 continue; 2600 2601 for (i=0, offset=MAPUNIT; i < cowdev->mapcount; 2602 i++, offset += MAPCHUNKSZ) { 2603 unsigned long numbytes; 2604 2605 if (i < (cowdev->mapcount-1)) 2606 /* 2607 ** full bitmap chunk 2608 */ 2609 numbytes = MAPCHUNKSZ; 2610 else 2611 /* 2612 ** last bitmap chunk: might be partly filled 2613 */ 2614 numbytes = cowdev->mapremain; 2615 2616 DEBUGP(DCOW 2617 "cowloop - flushing bitmap %2d (%3ld Kb)\n", 2618 i, numbytes/1024); 2619 2620 if (cowlo_writecowraw(cowdev, *(cowdev->mapcache+i), 2621 numbytes, offset) < numbytes) { 2622 break; 2623 } 2624 } 2625 2626 /* 2627 ** flush clean up-to-date cowhead to cowfile 2628 */ 2629 cowdev->cowhead->cowused = cowdev->nrcowblocks; 2630 cowdev->cowhead->flags &= ~COWDIRTY; 2631 2632 DEBUGP(DCOW "cowloop - flushing cowhead (%3d Kb)\n", 2633 MAPUNIT/1024); 2634 2635 cowlo_writecowraw(cowdev, cowdev->cowhead, MAPUNIT, (loff_t) 0); 2636 } 2637} 2638 2639/*****************************************************************************/ 2640/* Module loading/unloading */ 2641/*****************************************************************************/ 2642 2643/* 2644** called during insmod/modprobe 2645*/ 2646static int __init 2647cowlo_init_module(void) 2648{ 2649 int rv; 2650 int minor, uptocows; 2651 2652 revision[sizeof revision - 3] = '\0'; 2653 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"); 2656 2657 memset(allzeroes, 0, MAPUNIT); 2658 2659 /* 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. 2663 */ 2664 if ((maxcows < 1) || (maxcows > MAXCOWS)) { 2665 printk(KERN_WARNING 2666 "cowloop - maxcows exceeds maximum of %d\n", MAXCOWS); 2667 2668 maxcows = DFLCOWS; 2669 } 2670 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) { 2674 printk(KERN_WARNING 2675 "cowloop - can not alloc table for %d devs\n", maxcows); 2676 uptocows = 0; 2677 rv = -ENOMEM; 2678 goto error_out; 2679 } 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) { 2685 printk(KERN_WARNING 2686 "cowloop - can not alloc admin-struct for dev no %d\n", minor); 2687 2688 uptocows = minor; /* this is how far we got.... */ 2689 rv = -ENOMEM; 2690 goto error_out; 2691 } 2692 memset(cowdevall[minor], 0, sizeof(struct cowloop_device)); 2693 } 2694 uptocows = maxcows; /* we got all devices */ 2695 2696 sema_init(&cowdevlock, 1); 2697 2698 /* 2699 ** register cowloop module 2700 */ 2701 if ( register_blkdev(COWMAJOR, DEVICE_NAME) < 0) { 2702 printk(KERN_WARNING 2703 "cowloop - unable to get major %d for cowloop\n", COWMAJOR); 2704 rv = -EIO; 2705 goto error_out; 2706 } 2707 2708 /* 2709 ** create a directory below /proc to allocate a file 2710 ** for each cowdevice that is allocated later on 2711 */ 2712 cowlo_procdir = proc_mkdir("cow", NULL); 2713 2714 /* 2715 ** check if a cowdevice has to be opened during insmod/modprobe; 2716 ** two parameters should be specified then: rdofile= and cowfile= 2717 */ 2718 if( (rdofile[0] != '\0') && (cowfile[0] != '\0') ) { 2719 char *po = option; 2720 int wantrecover = 0; 2721 2722 /* 2723 ** check if automatic recovery is wanted 2724 */ 2725 while (*po) { 2726 if (*po == 'r') { 2727 wantrecover = 1; 2728 break; 2729 } 2730 po++; 2731 } 2732 2733 /* 2734 ** open new cowdevice with minor number 0 2735 */ 2736 if ( (rv = cowlo_openpair(rdofile, cowfile, wantrecover, 0))) { 2737 remove_proc_entry("cow", NULL); 2738 unregister_blkdev(COWMAJOR, DEVICE_NAME); 2739 goto error_out; 2740 } 2741 } else { 2742 /* 2743 ** check if only one parameter has been specified 2744 */ 2745 if( (rdofile[0] != '\0') || (cowfile[0] != '\0') ) { 2746 printk(KERN_ERR 2747 "cowloop - only one filename specified\n"); 2748 remove_proc_entry("cow", NULL); 2749 unregister_blkdev(COWMAJOR, DEVICE_NAME); 2750 rv = -EINVAL; 2751 goto error_out; 2752 } 2753 } 2754 2755 /* 2756 ** allocate fake disk as control channel to handle the requests 2757 ** to activate and deactivate cowdevices dynamically 2758 */ 2759 if (!(cowctlgd = alloc_disk(1))) { 2760 printk(KERN_WARNING 2761 "cowloop - unable to alloc_disk for cowctl\n"); 2762 2763 remove_proc_entry("cow", NULL); 2764 (void) cowlo_closepair(cowdevall[0]); 2765 unregister_blkdev(COWMAJOR, DEVICE_NAME); 2766 rv = -ENOMEM; 2767 goto error_out; 2768 } 2769 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); 2780 2781 add_disk(cowctlgd); 2782 2783 printk(KERN_NOTICE "cowloop - number of configured cowdevices: %d\n", 2784 maxcows); 2785 if (rdofile[0] != '\0') { 2786 printk(KERN_NOTICE "cowloop - initialized on rdofile=%s\n", 2787 rdofile); 2788 } else { 2789 printk(KERN_NOTICE "cowloop - initialized without rdofile yet\n"); 2790 } 2791 return 0; 2792 2793error_out: 2794 for (minor=0; minor < uptocows ; minor++) { 2795 kfree(cowdevall[minor]); 2796 } 2797 kfree(cowdevall); 2798 return rv; 2799} 2800 2801/* 2802** called during rmmod 2803*/ 2804static void __exit 2805cowlo_cleanup_module(void) 2806{ 2807 int minor; 2808 2809 /* 2810 ** flush bitmaps and cowheads to the cowfiles 2811 */ 2812 down(&cowdevlock); 2813 cowlo_sync(); 2814 up(&cowdevlock); 2815 2816 /* 2817 ** close all cowdevices 2818 */ 2819 for (minor=0; minor < maxcows; minor++) 2820 (void) cowlo_closepair(cowdevall[minor]); 2821 2822 unregister_blkdev(COWMAJOR, DEVICE_NAME); 2823 2824 /* 2825 ** get rid of /proc/cow and unregister the driver 2826 */ 2827 remove_proc_entry("cow", NULL); 2828 2829 for (minor = 0; minor < maxcows; minor++) { 2830 kfree(cowdevall[minor]); 2831 } 2832 kfree(cowdevall); 2833 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 */ 2837 2838 printk(KERN_NOTICE "cowloop - unloaded\n"); 2839} 2840 2841module_init(cowlo_init_module); 2842module_exit(cowlo_cleanup_module);