]> git.pld-linux.org Git - packages/kernel.git/blob - linux-lvm-1.0.1-2.4.17.patch
- added -r to depmod to actually check modules instead of rejecting
[packages/kernel.git] / linux-lvm-1.0.1-2.4.17.patch
1 --- linux/include/linux/lvm.h.orig      Sun Nov 11 18:09:32 2001
2 +++ linux/include/linux/lvm.h   Thu Jan 10 12:24:08 2002
3 @@ -3,28 +3,28 @@
4   * kernel/lvm.h
5   * tools/lib/lvm.h
6   *
7 - * Copyright (C) 1997 - 2000  Heinz Mauelshagen, Sistina Software
8 + * Copyright (C) 1997 - 2001  Heinz Mauelshagen, Sistina Software
9   *
10   * February-November 1997
11   * May-July 1998
12   * January-March,July,September,October,Dezember 1999
13   * January,February,July,November 2000
14 - * January 2001
15 + * January-March,June,July 2001
16   *
17   * lvm is free software; you can redistribute it and/or modify
18   * it under the terms of the GNU General Public License as published by
19   * the Free Software Foundation; either version 2, or (at your option)
20   * any later version.
21 - * 
22 + *
23   * lvm is distributed in the hope that it will be useful,
24   * but WITHOUT ANY WARRANTY; without even the implied warranty of
25   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26   * GNU General Public License for more details.
27 - * 
28 + *
29   * You should have received a copy of the GNU General Public License
30   * along with GNU CC; see the file COPYING.  If not, write to
31   * the Free Software Foundation, 59 Temple Place - Suite 330,
32 - * Boston, MA 02111-1307, USA. 
33 + * Boston, MA 02111-1307, USA.
34   *
35   */
36  
37 @@ -52,8 +52,7 @@
38   *    08/12/1999 - changed LVM_LV_SIZE_MAX macro to reflect current 1TB limit
39   *    01/01/2000 - extended lv_v2 core structure by wait_queue member
40   *    12/02/2000 - integrated Andrea Arcagnelli's snapshot work
41 - *    14/02/2001 - changed LVM_SNAPSHOT_MIN_CHUNK to 1 page
42 - *    18/02/2000 - seperated user and kernel space parts by 
43 + *    18/02/2000 - seperated user and kernel space parts by
44   *                 #ifdef them with __KERNEL__
45   *    08/03/2000 - implemented cluster/shared bits for vg_access
46   *    26/06/2000 - implemented snapshot persistency and resizing support
47 @@ -61,11 +60,18 @@
48   *    12/11/2000 - removed unneeded timestamp definitions
49   *    24/12/2000 - removed LVM_TO_{CORE,DISK}*, use cpu_{from, to}_le*
50   *                 instead - Christoph Hellwig
51 - *    01/03/2001 - Rename VG_CREATE to VG_CREATE_OLD and add new VG_CREATE
52 + *    22/01/2001 - Change ulong to uint32_t
53 + *    14/02/2001 - changed LVM_SNAPSHOT_MIN_CHUNK to 1 page
54 + *    20/02/2001 - incremented IOP version to 11 because of incompatible
55 + *                 change in VG activation (in order to support devfs better)
56 + *    01/03/2001 - Revert to IOP10 and add VG_CREATE_OLD call for compatibility
57   *    08/03/2001 - new lv_t (in core) version number 5: changed page member
58   *                 to (struct kiobuf *) to use for COW exception table io
59 - *    23/03/2001 - Change a (presumably) mistyped pv_t* to an lv_t*
60 - *    26/03/2001 - changed lv_v4 to lv_v5 in structure definition [HM]
61 + *    26/03/2001 - changed lv_v4 to lv_v5 in structure definition (HM)
62 + *    21/06/2001 - changed BLOCK_SIZE back to 1024 for non S/390
63 + *    22/06/2001 - added Andreas Dilger's PE on 4k boundary alignment enhancements
64 + *    19/07/2001 - added rwsem compatibility macros for 2.2 kernels
65 + *    13/11/2001 - reduced userspace inclusion of kernel headers to a minimum
66   *
67   */
68  
69 @@ -73,10 +79,10 @@
70  #ifndef _LVM_H_INCLUDE
71  #define _LVM_H_INCLUDE
72  
73 -#define LVM_RELEASE_NAME "1.0.1-rc4(ish)"
74 -#define LVM_RELEASE_DATE "03/10/2001"
75 +#define LVM_RELEASE_NAME "1.0.1"
76 +#define LVM_RELEASE_DATE "26/11/2001"
77  
78 -#define _LVM_KERNEL_H_VERSION   "LVM "LVM_RELEASE_NAME" ("LVM_RELEASE_DATE")"
79 +#define        _LVM_KERNEL_H_VERSION   "LVM "LVM_RELEASE_NAME" ("LVM_RELEASE_DATE")"
80  
81  #include <linux/version.h>
82  
83 @@ -98,16 +104,26 @@
84     #define DEBUG_READ
85     #define DEBUG_GENDISK
86     #define DEBUG_VG_CREATE
87 -   #define DEBUG_LVM_BLK_OPEN
88 +   #define DEBUG_DEVICE
89     #define DEBUG_KFREE
90   */
91 -#endif                         /* #ifdef __KERNEL__ */
92  
93  #include <linux/kdev_t.h>
94  #include <linux/list.h>
95 -
96  #include <asm/types.h>
97  #include <linux/major.h>
98 +#else
99 +/* This prevents the need to include <linux/list.h> which
100 +   causes problems on some platforms. It's not nice but then
101 +   neither is the alternative. */
102 +struct list_head {
103 +        struct list_head *next, *prev;
104 +};
105 +#define __KERNEL__
106 +#include <linux/kdev_t.h>
107 +#undef __KERNEL__
108 +#endif                         /* #ifndef __KERNEL__ */
109 +
110  
111  #ifdef __KERNEL__
112  #include <linux/spinlock.h>
113 @@ -115,6 +131,7 @@
114  #include <asm/semaphore.h>
115  #endif                         /* #ifdef __KERNEL__ */
116  
117 +
118  #include <asm/page.h>
119  
120  #if !defined ( LVM_BLK_MAJOR) || !defined ( LVM_CHAR_MAJOR)
121 @@ -125,7 +142,7 @@
122  #undef BLOCK_SIZE
123  #endif
124  
125 -#ifdef CONFIG_ARCH_S390 
126 +#ifdef CONFIG_ARCH_S390
127  #define BLOCK_SIZE     4096
128  #else
129  #define BLOCK_SIZE     1024
130 @@ -189,6 +206,38 @@
131  
132  
133  /*
134 + * VGDA: default disk spaces and offsets
135 + *
136 + *   there's space after the structures for later extensions.
137 + *
138 + *   offset            what                                size
139 + *   ---------------   ----------------------------------  ------------
140 + *   0                 physical volume structure           ~500 byte
141 + *
142 + *   1K                volume group structure              ~200 byte
143 + *
144 + *   6K                namelist of physical volumes        128 byte each
145 + *
146 + *   6k + n * ~300byte n logical volume structures         ~300 byte each
147 + *
148 + *   + m * 4byte       m physical extent alloc. structs    4 byte each
149 + *
150 + *   End of disk -     first physical extent               typically 4 megabyte
151 + *   PE total *
152 + *   PE size
153 + *
154 + *
155 + */
156 +
157 +/* DONT TOUCH THESE !!! */
158 +
159 +
160 +
161 +
162 +
163 +
164 +
165 +/*
166   * LVM_PE_T_MAX corresponds to:
167   *
168   * 8KB PE size can map a ~512 MB logical volume at the cost of 1MB memory,
169 @@ -217,8 +266,9 @@
170  #define        LVM_MAX_STRIPES         128     /* max # of stripes */
171  #define        LVM_MAX_SIZE            ( 1024LU * 1024 / SECTOR_SIZE * 1024 * 1024)    /* 1TB[sectors] */
172  #define        LVM_MAX_MIRRORS         2       /* future use */
173 -#define        LVM_MIN_READ_AHEAD      2       /* minimum read ahead sectors */
174 -#define        LVM_MAX_READ_AHEAD      120     /* maximum read ahead sectors */
175 +#define        LVM_MIN_READ_AHEAD      0       /* minimum read ahead sectors */
176 +#define        LVM_DEFAULT_READ_AHEAD  1024    /* sectors for 512k scsi segments */
177 +#define        LVM_MAX_READ_AHEAD      10000   /* maximum read ahead sectors */
178  #define        LVM_MAX_LV_IO_TIMEOUT   60      /* seconds I/O timeout (future use) */
179  #define        LVM_PARTITION           0xfe    /* LVM partition id */
180  #define        LVM_NEW_PARTITION       0x8e    /* new LVM partition id (10/09/1999) */
181 @@ -298,7 +348,12 @@
182  #endif
183  
184  /* lock the logical volume manager */
185 +#if LVM_DRIVER_IOP_VERSION > 11
186 +#define        LVM_LOCK_LVM            _IO ( 0xfe, 0x9A)
187 +#else
188 +/* This is actually the same as _IO ( 0xff, 0x00), oops.  Remove for IOP 12+ */
189  #define        LVM_LOCK_LVM            _IO ( 0xfe, 0x100)
190 +#endif
191  /* END ioctls */
192  
193  
194 @@ -495,9 +550,9 @@
195         uint lv_read_ahead;
196  
197         /* delta to version 1 starts here */
198 -       struct lv_v5 *lv_snapshot_org;
199 -       struct lv_v5 *lv_snapshot_prev;
200 -       struct lv_v5 *lv_snapshot_next;
201 +       struct lv_v5 *lv_snapshot_org;
202 +       struct lv_v5 *lv_snapshot_prev;
203 +       struct lv_v5 *lv_snapshot_next;
204         lv_block_exception_t *lv_block_exception;
205         uint lv_remap_ptr;
206         uint lv_remap_end;
207 @@ -661,6 +716,7 @@
208  } lv_snapshot_use_rate_req_t;
209  
210  
211 +
212  /* useful inlines */
213  static inline ulong round_up(ulong n, ulong size) {
214         size--;
215 @@ -671,6 +727,7 @@
216         return round_up(n, size) / size;
217  }
218  
219 +/* FIXME: nasty capital letters */
220  static int inline LVM_GET_COW_TABLE_CHUNKS_PER_PE(vg_t *vg, lv_t *lv) {
221         return vg->pe_size / lv->lv_chunk_size;
222  }
223 @@ -693,4 +750,6 @@
224         return entries;
225  }
226  
227 +
228  #endif                         /* #ifndef _LVM_H_INCLUDE */
229 +
230 --- linux/drivers/md/lvm.c.orig Mon Nov 19 17:56:04 2001
231 +++ linux/drivers/md/lvm.c      Thu Jan 10 12:24:08 2002
232 @@ -1,13 +1,13 @@
233  /*
234   * kernel/lvm.c
235   *
236 - * Copyright (C) 1997 - 2000  Heinz Mauelshagen, Sistina Software
237 + * Copyright (C) 1997 - 2001  Heinz Mauelshagen, Sistina Software
238   *
239   * February-November 1997
240   * April-May,July-August,November 1998
241   * January-March,May,July,September,October 1999
242   * January,February,July,September-November 2000
243 - * January 2001
244 + * January-April 2001
245   *
246   *
247   * LVM driver is free software; you can redistribute it and/or modify
248 @@ -43,7 +43,8 @@
249   *                 support for free (eg. longer) logical volume names
250   *    12/05/1998 - added spin_locks (thanks to Pascal van Dam
251   *                 <pascal@ramoth.xs4all.nl>)
252 - *    25/05/1998 - fixed handling of locked PEs in lvm_map() and lvm_chr_ioctl()
253 + *    25/05/1998 - fixed handling of locked PEs in lvm_map() and
254 + *                 lvm_chr_ioctl()
255   *    26/05/1998 - reactivated verify_area by access_ok
256   *    07/06/1998 - used vmalloc/vfree instead of kmalloc/kfree to go
257   *                 beyond 128/256 KB max allocation limit per call
258 @@ -125,7 +126,8 @@
259   *    14/02/2000 - support for 2.3.43
260   *               - integrated Andrea Arcagneli's snapshot code
261   *    25/06/2000 - james (chip) , IKKHAYD! roffl
262 - *    26/06/2000 - enhanced lv_extend_reduce for snapshot logical volume support
263 + *    26/06/2000 - enhanced lv_extend_reduce for snapshot logical volume
264 + *                 support
265   *    06/09/2000 - added devfs support
266   *    07/09/2000 - changed IOP version to 9
267   *               - started to add new char ioctl LV_STATUS_BYDEV_T to support
268 @@ -147,15 +149,24 @@
269   *    08/01/2001 - Removed conditional compiles related to PROC_FS,
270   *                 procfs is always supported now. (JT)
271   *    12/01/2001 - avoided flushing logical volume in case of shrinking
272 - *                 because of unnecessary overhead in case of heavy updates
273 + *                 because of unecessary overhead in case of heavy updates
274   *    25/01/2001 - Allow RO open of an inactive LV so it can be reactivated.
275 - *    31/01/2001 - If you try and BMAP a snapshot you now get an -EPERM
276 - *    01/02/2001 - factored __remap_snapshot out of lvm_map
277 + *    31/01/2001 - removed blk_init_queue/blk_cleanup_queue queueing will be
278 + *                 handled by the proper devices.
279 + *               - If you try and BMAP a snapshot you now get an -EPERM
280 + *    01/01/2001 - lvm_map() now calls buffer_IO_error on error for 2.4
281 + *               - factored __remap_snapshot out of lvm_map
282   *    12/02/2001 - move devfs code to create VG before LVs
283 - *    14/02/2001 - tidied device defines for blk.h
284 + *    13/02/2001 - allow VG_CREATE on /dev/lvm
285 + *    14/02/2001 - removed modversions.h
286 + *               - tidied device defines for blk.h
287   *               - tidied debug statements
288 + *               - bug: vg[] member not set back to NULL if activation fails
289   *               - more lvm_map tidying
290 - *    14/02/2001 - bug: vg[] member not set back to NULL if activation fails
291 + *    15/02/2001 - register /dev/lvm with devfs correctly (major/minor
292 + *                 were swapped)
293 + *    19/02/2001 - preallocated buffer_heads for rawio when using
294 + *                 snapshots [JT]
295   *    28/02/2001 - introduced the P_DEV macro and changed some internel
296   *                 functions to be static [AD]
297   *    28/02/2001 - factored lvm_get_snapshot_use_rate out of blk_ioctl [AD]
298 @@ -163,25 +174,50 @@
299   *                 where the check for an existing LV takes place right at
300   *                 the beginning
301   *    01/03/2001 - Add VG_CREATE_OLD for IOP 10 compatibility
302 - *    02/03/2001 - Don't destroy usermode pointers in lv_t structures duing LV_
303 - *                 STATUS_BYxxx and remove redundant lv_t variables from same.
304 + *    02/03/2001 - Don't destroy usermode pointers in lv_t structures duing
305 + *                 LV_STATUS_BYxxx
306 + *                 and remove redundant lv_t variables from same.
307 + *               - avoid compilation of lvm_dummy_device_request in case of
308 + *                 Linux >= 2.3.0 to avoid a warning
309 + *               - added lvm_name argument to printk in buffer allocation
310 + *                 in order to avoid a warning
311 + *    04/03/2001 - moved linux/version.h above first use of KERNEL_VERSION
312 + *                 macros
313   *    05/03/2001 - restore copying pe_t array in lvm_do_lv_status_byname. For
314   *                 lvdisplay -v (PC)
315   *               - restore copying pe_t array in lvm_do_lv_status_byindex (HM)
316   *               - added copying pe_t array in lvm_do_lv_status_bydev (HM)
317   *               - enhanced lvm_do_lv_status_by{name,index,dev} to be capable
318   *                 to copy the lv_block_exception_t array to userspace (HM)
319 - *    08/03/2001 - factored lvm_do_pv_flush out of lvm_chr_ioctl [HM]
320 + *    08/03/2001 - initialize new lv_ptr->lv_COW_table_iobuf for snapshots;
321 + *                 removed obsolete lv_ptr->lv_COW_table_page initialization
322 + *               - factored lvm_do_pv_flush out of lvm_chr_ioctl (HM)
323   *    09/03/2001 - Added _lock_open_count to ensure we only drop the lock
324   *                 when the locking process closes.
325 - *    05/04/2001 - lvm_map bugs: don't use b_blocknr/b_dev in lvm_map, it
326 - *                destroys stacking devices. call b_end_io on failed maps.
327 - *                (Jens Axboe)
328 - *               - Defer writes to an extent that is being moved [JT + AD]
329 - *    28/05/2001 - implemented missing BLKSSZGET ioctl [AD]
330 + *    05/04/2001 - Defer writes to an extent that is being moved [JT]
331 + *    05/04/2001 - use b_rdev and b_rsector rather than b_dev and b_blocknr in
332 + *                 lvm_map() in order to make stacking devices more happy (HM)
333 + *    11/04/2001 - cleaned up the pvmove queue code. I no longer retain the
334 + *                 rw flag, instead WRITEA's are just dropped [JT]
335 + *    30/04/2001 - added KERNEL_VERSION > 2.4.3 get_hardsect_size() rather
336 + *                 than get_hardblocksize() call
337 + *    03/05/2001 - Use copy_to/from_user to preserve pointers in
338 + *                 lvm_do_status_by*
339 + *    11/05/2001 - avoid accesses to inactive snapshot data in
340 + *                 __update_hardsectsize() and lvm_do_lv_extend_reduce() (JW)
341 + *    28/05/2001 - implemented missing BLKSSZGET ioctl
342 + *    05/06/2001 - Move _pe_lock out of fast path for lvm_map when no PEs
343 + *                 locked.  Make buffer queue flush not need locking.
344 + *                 Fix lvm_user_bmap() to set b_rsector for new lvm_map(). [AED]
345 + *    30/06/2001 - Speed up __update_hardsectsize() by checking if PVs have
346 + *                 the same hardsectsize (very likely) before scanning all LEs
347 + *                 in the LV each time.  [AED]
348 + *    12/10/2001 - Use add/del_gendisk() routines in 2.4.10+
349 + *    01/11/2001 - Backport read_ahead change from Linus kernel [AED]
350   *
351   */
352  
353 +#include <linux/version.h>
354  
355  #define MAJOR_NR LVM_BLK_MAJOR
356  #define DEVICE_OFF(device)
357 @@ -191,11 +227,10 @@
358  /* #define     LVM_VFS_ENHANCEMENT */
359  
360  #include <linux/config.h>
361 -
362  #include <linux/module.h>
363 -
364  #include <linux/kernel.h>
365  #include <linux/vmalloc.h>
366 +
367  #include <linux/slab.h>
368  #include <linux/init.h>
369  
370 @@ -206,6 +241,8 @@
371  #include <linux/blkdev.h>
372  #include <linux/genhd.h>
373  #include <linux/locks.h>
374 +
375 +
376  #include <linux/devfs_fs_kernel.h>
377  #include <linux/smp_lock.h>
378  #include <asm/ioctl.h>
379 @@ -224,9 +261,13 @@
380  
381  #include "lvm-internal.h"
382  
383 -#define        LVM_CORRECT_READ_AHEAD( a) \
384 -   if      ( a < LVM_MIN_READ_AHEAD || \
385 -             a > LVM_MAX_READ_AHEAD) a = LVM_MAX_READ_AHEAD;
386 +#define        LVM_CORRECT_READ_AHEAD(a)               \
387 +do {                                           \
388 +       if ((a) < LVM_MIN_READ_AHEAD ||         \
389 +           (a) > LVM_MAX_READ_AHEAD)           \
390 +               (a) = LVM_DEFAULT_READ_AHEAD;   \
391 +       read_ahead[MAJOR_NR] = (a);             \
392 +} while(0)
393  
394  #ifndef WRITEA
395  #  define WRITEA WRITE
396 @@ -351,6 +392,7 @@
397  
398  
399  struct file_operations lvm_chr_fops = {
400 +       owner:          THIS_MODULE,
401         open:           lvm_chr_open,
402         release:        lvm_chr_close,
403         ioctl:          lvm_chr_ioctl,
404 @@ -360,7 +402,7 @@
405  struct block_device_operations lvm_blk_dops =
406  {
407         owner:          THIS_MODULE,
408 -       open:           lvm_blk_open,
409 +       open:           lvm_blk_open,
410         release:        lvm_blk_close,
411         ioctl:          lvm_blk_ioctl,
412  };
413 @@ -383,6 +425,7 @@
414         nr_real:        MAX_LV,
415  };
416  
417 +
418  /*
419   * Driver initialization...
420   */
421 @@ -394,7 +437,6 @@
422                        lvm_name);
423                 return -EIO;
424         }
425 -
426         if (devfs_register_blkdev(MAJOR_NR, lvm_name, &lvm_blk_dops) < 0)
427         {
428                 printk("%s -- devfs_register_blkdev failed\n", lvm_name);
429 @@ -409,6 +451,7 @@
430         lvm_init_vars();
431         lvm_geninit(&lvm_gendisk);
432  
433 +       /* insert our gendisk at the corresponding major */
434         add_gendisk(&lvm_gendisk);
435  
436  #ifdef LVM_HD_NAME
437 @@ -436,10 +479,10 @@
438         return 0;
439  } /* lvm_init() */
440  
441 -
442  /*
443   * cleanup...
444   */
445 +
446  static void lvm_cleanup(void)
447  {
448         if (devfs_unregister_chrdev(LVM_CHAR_MAJOR, lvm_name) < 0)
449 @@ -449,6 +492,9 @@
450                 printk(KERN_ERR "%s -- devfs_unregister_blkdev failed\n",
451                        lvm_name);
452  
453 +
454 +
455 +       /* delete our gendisk from chain */
456         del_gendisk(&lvm_gendisk);
457  
458         blk_size[MAJOR_NR] = NULL;
459 @@ -514,7 +560,7 @@
460   */
461  static int lvm_chr_open(struct inode *inode, struct file *file)
462  {
463 -       unsigned int minor = MINOR(inode->i_rdev);
464 +       int minor = MINOR(inode->i_rdev);
465  
466         P_DEV("chr_open MINOR: %d  VG#: %d  mode: %s%s  lock: %d\n",
467               minor, VG_CHR(minor), MODE_TO_STR(file->f_mode), lock);
468 @@ -525,10 +571,10 @@
469         /* Group special file open */
470         if (VG_CHR(minor) > MAX_VG) return -ENXIO;
471  
472 -       spin_lock(&lvm_lock);
473 -       if(lock == current->pid)
474 -               _lock_open_count++;
475 -       spin_unlock(&lvm_lock);
476 +       spin_lock(&lvm_lock);
477 +       if(lock == current->pid)
478 +               _lock_open_count++;
479 +       spin_unlock(&lvm_lock);
480  
481         lvm_chr_open_count++;
482  
483 @@ -546,7 +592,7 @@
484   *
485   */
486  static int lvm_chr_ioctl(struct inode *inode, struct file *file,
487 -                 uint command, ulong a)
488 +                        uint command, ulong a)
489  {
490         int minor = MINOR(inode->i_rdev);
491         uint extendable, l, v;
492 @@ -610,8 +656,8 @@
493                 /* create a VGDA */
494                 return lvm_do_vg_create(arg, minor);
495  
496 -       case VG_CREATE:
497 -               /* create a VGDA, assume VG number is filled in */
498 +       case VG_CREATE:
499 +               /* create a VGDA, assume VG number is filled in */
500                 return lvm_do_vg_create(arg, -1);
501  
502         case VG_EXTEND:
503 @@ -734,7 +780,7 @@
504  
505         case PV_FLUSH:
506                 /* physical volume buffer flush/invalidate */
507 -               return lvm_do_pv_flush(arg);
508 +               return lvm_do_pv_flush(arg);
509  
510  
511         default:
512 @@ -765,16 +811,16 @@
513  
514         if (lvm_chr_open_count > 0) lvm_chr_open_count--;
515  
516 -       spin_lock(&lvm_lock);
517 -       if(lock == current->pid) {
518 -               if(!_lock_open_count) {
519 +       spin_lock(&lvm_lock);
520 +       if(lock == current->pid) {
521 +               if(!_lock_open_count) {
522                         P_DEV("chr_close: unlocking LVM for pid %d\n", lock);
523 -                       lock = 0;
524 -                       wake_up_interruptible(&lvm_wait);
525 -               } else
526 -                       _lock_open_count--;
527 +                       lock = 0;
528 +                       wake_up_interruptible(&lvm_wait);
529 +               } else
530 +                       _lock_open_count--;
531         }
532 -       spin_unlock(&lvm_lock);
533 +       spin_unlock(&lvm_lock);
534  
535         MOD_DEC_USE_COUNT;
536  
537 @@ -860,7 +906,7 @@
538         switch (command) {
539         case BLKSSZGET:
540                 /* get block device sector size as needed e.g. by fdisk */
541 -               return put_user(get_hardsect_size(inode->i_rdev), (int *) arg);
542 +               return put_user(lvm_sectsize(inode->i_rdev), (int *) arg);
543  
544         case BLKGETSIZE:
545                 /* return device size */
546 @@ -869,11 +915,12 @@
547                         return -EFAULT;
548                 break;
549  
550 +#ifdef BLKGETSIZE64
551         case BLKGETSIZE64:
552                 if (put_user((u64)lv_ptr->lv_size << 9, (u64 *)arg))
553                         return -EFAULT;
554                 break;
555 -
556 +#endif
557  
558         case BLKFLSBUF:
559                 /* flush buffer cache */
560 @@ -897,6 +944,7 @@
561                     (long) arg > LVM_MAX_READ_AHEAD)
562                         return -EINVAL;
563                 lv_ptr->lv_read_ahead = (long) arg;
564 +               read_ahead[MAJOR_NR] = lv_ptr->lv_read_ahead;
565                 break;
566  
567  
568 @@ -955,12 +1003,13 @@
569                 break;
570  
571         case LV_BMAP:
572 -                /* turn logical block into (dev_t, block).  non privileged. */
573 -                /* don't bmap a snapshot, since the mapping can change */
574 -               if(lv_ptr->lv_access & LV_SNAPSHOT)
575 +               /* turn logical block into (dev_t, block). non privileged. */
576 +               /* don't bmap a snapshot, since the mapping can change */
577 +               if (lv_ptr->lv_access & LV_SNAPSHOT)
578                         return -EPERM;
579  
580                 return lvm_user_bmap(inode, (struct lv_bmap *) arg);
581 +               break;
582  
583         case LV_SET_ALLOCATION:
584                 /* set allocation flags of a logical volume */
585 @@ -1048,7 +1097,7 @@
586         bh.b_blocknr = block;
587         bh.b_dev = bh.b_rdev = inode->i_rdev;
588         bh.b_size = lvm_get_blksize(bh.b_dev);
589 -       bh.b_rsector = block * (bh.b_size >> 9);
590 +       bh.b_rsector = block * (bh.b_size >> 9);
591         if ((err=lvm_map(&bh, READ)) < 0)  {
592                 printk("lvm map failed: %d\n", err);
593                 return -EINVAL;
594 @@ -1056,7 +1105,7 @@
595  
596         return put_user(kdev_t_to_nr(bh.b_rdev), &user_result->lv_dev) ||
597                put_user(bh.b_rsector/(bh.b_size>>9), &user_result->lv_block) ?
598 -              -EFAULT : 0;
599 +               -EFAULT : 0;
600  }
601  
602  
603 @@ -1065,7 +1114,7 @@
604   * (see init_module/lvm_init)
605   */
606  static void __remap_snapshot(kdev_t rdev, ulong rsector,
607 -                            ulong pe_start, lv_t *lv, vg_t *vg) {
608 +                                   ulong pe_start, lv_t *lv, vg_t *vg) {
609  
610         /* copy a chunk from the origin to a snapshot device */
611         down_write(&lv->lv_lock);
612 @@ -1122,6 +1171,7 @@
613         return 0;
614  }
615  
616 +
617  static int lvm_map(struct buffer_head *bh, int rw)
618  {
619         int minor = MINOR(bh->b_rdev);
620 @@ -1223,10 +1273,8 @@
621                 goto out;
622  
623         if (lv->lv_access & LV_SNAPSHOT) { /* remap snapshot */
624 -               if (lv->lv_block_exception)
625 -                       lvm_snapshot_remap_block(&rdev_map, &rsector_map,
626 -                                                pe_start, lv);
627 -               else
628 +               if (lvm_snapshot_remap_block(&rdev_map, &rsector_map,
629 +                                            pe_start, lv) < 0)
630                         goto bad;
631  
632         } else if (rw == WRITE || rw == WRITEA) { /* snapshot origin */
633 @@ -1245,7 +1293,7 @@
634                         _remap_snapshot(rdev_map, rsector_map,
635                                          pe_start, snap, vg_this);
636                 }
637 -       }
638 +       }
639  
640   out:
641         bh->b_rdev = rdev_map;
642 @@ -1284,12 +1332,15 @@
643  #endif
644  
645  
646 +
647 +
648  /*
649   * make request function
650   */
651  static int lvm_make_request_fn(request_queue_t *q,
652                                int rw,
653 -                              struct buffer_head *bh) {
654 +                              struct buffer_head *bh)
655 +{
656         return (lvm_map(bh, rw) <= 0) ? 0 : 1;
657  }
658  
659 @@ -1457,14 +1508,14 @@
660                 return -EFAULT;
661         }
662  
663 -        /* VG_CREATE now uses minor number in VG structure */
664 -        if (minor == -1) minor = vg_ptr->vg_number;
665 +       /* VG_CREATE now uses minor number in VG structure */
666 +       if (minor == -1) minor = vg_ptr->vg_number;
667  
668         /* Validate it */
669 -        if (vg[VG_CHR(minor)] != NULL) {
670 +       if (vg[VG_CHR(minor)] != NULL) {
671                 P_IOCTL("lvm_do_vg_create ERROR: VG %d in use\n", minor);
672                 kfree(vg_ptr);
673 -               return -EPERM;
674 +               return -EPERM;
675         }
676  
677         /* we are not that active so far... */
678 @@ -1637,7 +1688,8 @@
679         lv_t *lv_ptr = NULL;
680         pv_t *pv_ptr = NULL;
681  
682 -       if (vg_ptr == NULL) return -ENXIO;
683 +       /* If the VG doesn't exist in the kernel then just exit */
684 +       if (!vg_ptr) return 0;
685  
686         if (copy_from_user(vg_name, arg, sizeof(vg_name)) != 0)
687                 return -EFAULT;
688 @@ -1797,30 +1849,56 @@
689  }
690  
691  
692 -static void __update_hardsectsize(lv_t *lv) {
693 -       int le, e;
694 -       int max_hardsectsize = 0, hardsectsize;
695 -
696 -       for (le = 0; le < lv->lv_allocated_le; le++) {
697 -               hardsectsize = get_hardsect_size(lv->lv_current_pe[le].dev);
698 -               if (hardsectsize == 0)
699 -                       hardsectsize = 512;
700 -               if (hardsectsize > max_hardsectsize)
701 -                       max_hardsectsize = hardsectsize;
702 -       }
703 -
704 -       /* only perform this operation on active snapshots */
705 -       if ((lv->lv_access & LV_SNAPSHOT) &&
706 -           (lv->lv_status & LV_ACTIVE)) {
707 -               for (e = 0; e < lv->lv_remap_end; e++) {
708 -                       hardsectsize = get_hardsect_size( lv->lv_block_exception[e].rdev_new);
709 -                       if (hardsectsize == 0)
710 -                               hardsectsize = 512;
711 -                       if (hardsectsize > max_hardsectsize)
712 +static void __update_hardsectsize(lv_t *lv)
713 +{
714 +       int max_hardsectsize = 0, hardsectsize = 0;
715 +       int p;
716 +
717 +       /* Check PVs first to see if they all have same sector size */
718 +       for (p = 0; p < lv->vg->pv_cur; p++) {
719 +               pv_t *pv = lv->vg->pv[p];
720 +               if (pv && (hardsectsize = lvm_sectsize(pv->pv_dev))) {
721 +                       if (max_hardsectsize == 0)
722                                 max_hardsectsize = hardsectsize;
723 +                       else if (hardsectsize != max_hardsectsize) {
724 +                               P_DEV("%s PV[%d] (%s) sector size %d, not %d\n",
725 +                                     lv->lv_name, p, kdevname(pv->pv_dev),
726 +                                     hardsectsize, max_hardsectsize);
727 +                               break;
728 +                       }
729                 }
730         }
731  
732 +       /* PVs have different block size, need to check each LE sector size */
733 +       if (hardsectsize != max_hardsectsize) {
734 +               int le;
735 +               for (le = 0; le < lv->lv_allocated_le; le++) {
736 +                       hardsectsize = lvm_sectsize(lv->lv_current_pe[le].dev);
737 +                       if (hardsectsize > max_hardsectsize) {
738 +                               P_DEV("%s LE[%d] (%s) blocksize %d not %d\n",
739 +                                     lv->lv_name, le,
740 +                                     kdevname(lv->lv_current_pe[le].dev),
741 +                                     hardsectsize, max_hardsectsize);
742 +                               max_hardsectsize = hardsectsize;
743 +                       }
744 +               }
745 +
746 +               /* only perform this operation on active snapshots */
747 +               if ((lv->lv_access & LV_SNAPSHOT) &&
748 +                   (lv->lv_status & LV_ACTIVE)) {
749 +                       int e;
750 +                       for (e = 0; e < lv->lv_remap_end; e++) {
751 +                               hardsectsize = lvm_sectsize(lv->lv_block_exception[e].rdev_new);
752 +                               if (hardsectsize > max_hardsectsize)
753 +                                       max_hardsectsize = hardsectsize;
754 +                       }
755 +               }
756 +       }
757 +
758 +       if (max_hardsectsize == 0)
759 +               max_hardsectsize = SECTOR_SIZE;
760 +       P_DEV("hardblocksize for LV %s is %d\n",
761 +             kdevname(lv->lv_dev), max_hardsectsize);
762         lvm_hardsectsizes[MINOR(lv->lv_dev)] = max_hardsectsize;
763  }
764  
765 @@ -1876,7 +1954,7 @@
766         lv_ptr->lv_snapshot_next = NULL;
767         lv_ptr->lv_block_exception = NULL;
768         lv_ptr->lv_iobuf = NULL;
769 -       lv_ptr->lv_COW_table_iobuf = NULL;
770 +       lv_ptr->lv_COW_table_iobuf = NULL;
771         lv_ptr->lv_snapshot_hash_table = NULL;
772         lv_ptr->lv_snapshot_hash_table_size = 0;
773         lv_ptr->lv_snapshot_hash_mask = 0;
774 @@ -1926,7 +2004,7 @@
775                         if (lv_ptr->lv_snapshot_org != NULL) {
776                                 size = lv_ptr->lv_remap_end * sizeof(lv_block_exception_t);
777  
778 -                               if(!size) {
779 +                               if (!size) {
780                                         printk(KERN_WARNING
781                                                "%s -- zero length exception table requested\n",
782                                                lvm_name);
783 @@ -1956,12 +2034,11 @@
784                                    LVM_SNAPSHOT_DROPPED_SECTOR)
785                                 {
786                                         printk(KERN_WARNING
787 -    "%s -- lvm_do_lv_create: snapshot has been dropped and will not be activated\n",
788 +   "%s -- lvm_do_lv_create: snapshot has been dropped and will not be activated\n",
789                                                lvm_name);
790                                         activate = 0;
791                                 }
792  
793 -
794                                 /* point to the original logical volume */
795                                 lv_ptr = lv_ptr->lv_snapshot_org;
796  
797 @@ -1995,11 +2072,11 @@
798                                                        lv_ptr->lv_block_exception[e].rsector_org, lv_ptr);
799                                 /* need to fill the COW exception table data
800                                    into the page for disk i/o */
801 -                               if(lvm_snapshot_fill_COW_page(vg_ptr, lv_ptr)) {
802 -                                       kfree(lv_ptr);
803 -                                       vg_ptr->lv[l] = NULL;
804 -                                       return -EINVAL;
805 -                               }
806 +                               if(lvm_snapshot_fill_COW_page(vg_ptr, lv_ptr)) {
807 +                                       kfree(lv_ptr);
808 +                                       vg_ptr->lv[l] = NULL;
809 +                                       return -EINVAL;
810 +                               }
811                                 init_waitqueue_head(&lv_ptr->lv_snapshot_wait);
812                         } else {
813                                 kfree(lv_ptr);
814 @@ -2022,6 +2099,7 @@
815         LVM_CORRECT_READ_AHEAD(lv_ptr->lv_read_ahead);
816         vg_ptr->lv_cur++;
817         lv_ptr->lv_status = lv_status_save;
818 +       lv_ptr->vg = vg_ptr;
819  
820         __update_hardsectsize(lv_ptr);
821  
822 @@ -2040,6 +2118,7 @@
823                 org->lv_access |= LV_SNAPSHOT_ORG;
824                 lv_ptr->lv_access &= ~LV_SNAPSHOT_ORG; /* this can only hide an userspace bug */
825  
826 +
827                 /* Link in the list of snapshot volumes */
828                 for (last = org; last->lv_snapshot_next; last = last->lv_snapshot_next);
829                 lv_ptr->lv_snapshot_prev = last;
830 @@ -2064,11 +2143,8 @@
831                 unlockfs(lv_ptr->lv_snapshot_org->lv_dev);
832  #endif
833  
834 -       lv_ptr->vg = vg_ptr;
835 -
836         lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].de =
837 -               lvm_fs_create_lv(vg_ptr, lv_ptr);
838 -
839 +           lvm_fs_create_lv(vg_ptr, lv_ptr);
840         return 0;
841  } /* lvm_do_lv_create() */
842  
843 @@ -2184,214 +2260,213 @@
844   * logical volume extend / reduce
845   */
846  static int __extend_reduce_snapshot(vg_t *vg_ptr, lv_t *old_lv, lv_t *new_lv) {
847 -        ulong size;
848 -        lv_block_exception_t *lvbe;
849 +       ulong size;
850 +       lv_block_exception_t *lvbe;
851  
852 -        if (!new_lv->lv_block_exception)
853 -                return -ENXIO;
854 +       if (!new_lv->lv_block_exception)
855 +               return -ENXIO;
856 +
857 +       size = new_lv->lv_remap_end * sizeof(lv_block_exception_t);
858 +       if ((lvbe = vmalloc(size)) == NULL) {
859 +               printk(KERN_CRIT
860 +                      "%s -- lvm_do_lv_extend_reduce: vmalloc "
861 +                      "error LV_BLOCK_EXCEPTION of %lu Byte at line %d\n",
862 +                      lvm_name, size, __LINE__);
863 +               return -ENOMEM;
864 +       }
865 +
866 +       if ((new_lv->lv_remap_end > old_lv->lv_remap_end) &&
867 +           (copy_from_user(lvbe, new_lv->lv_block_exception, size))) {
868 +               vfree(lvbe);
869 +               return -EFAULT;
870 +       }
871 +       new_lv->lv_block_exception = lvbe;
872  
873 -        size = new_lv->lv_remap_end * sizeof(lv_block_exception_t);
874 -        if ((lvbe = vmalloc(size)) == NULL) {
875 -                printk(KERN_CRIT
876 -                       "%s -- lvm_do_lv_extend_reduce: vmalloc "
877 -                       "error LV_BLOCK_EXCEPTION of %lu Byte at line %d\n",
878 -                       lvm_name, size, __LINE__);
879 -                return -ENOMEM;
880 -        }
881 -
882 -        if ((new_lv->lv_remap_end > old_lv->lv_remap_end) &&
883 -            (copy_from_user(lvbe, new_lv->lv_block_exception, size))) {
884 -                vfree(lvbe);
885 -                return -EFAULT;
886 -        }
887 -        new_lv->lv_block_exception = lvbe;
888 -
889 -        if (lvm_snapshot_alloc_hash_table(new_lv)) {
890 -                vfree(new_lv->lv_block_exception);
891 -                return -ENOMEM;
892 -        }
893 +       if (lvm_snapshot_alloc_hash_table(new_lv)) {
894 +               vfree(new_lv->lv_block_exception);
895 +               return -ENOMEM;
896 +       }
897  
898 -        return 0;
899 +       return 0;
900  }
901  
902  static int __extend_reduce(vg_t *vg_ptr, lv_t *old_lv, lv_t *new_lv) {
903 -        ulong size, l, p, end;
904 -        pe_t *pe;
905 +       ulong size, l, p, end;
906 +       pe_t *pe;
907 +
908 +       /* allocate space for new pe structures */
909 +       size = new_lv->lv_current_le * sizeof(pe_t);
910 +       if ((pe = vmalloc(size)) == NULL) {
911 +               printk(KERN_CRIT
912 +                      "%s -- lvm_do_lv_extend_reduce: "
913 +                      "vmalloc error LV_CURRENT_PE of %lu Byte at line %d\n",
914 +                      lvm_name, size, __LINE__);
915 +               return -ENOMEM;
916 +       }
917 +
918 +       /* get the PE structures from user space */
919 +       if (copy_from_user(pe, new_lv->lv_current_pe, size)) {
920 +               if(old_lv->lv_access & LV_SNAPSHOT)
921 +                       vfree(new_lv->lv_snapshot_hash_table);
922 +               vfree(pe);
923 +               return -EFAULT;
924 +       }
925 +
926 +       new_lv->lv_current_pe = pe;
927 +
928 +       /* reduce allocation counters on PV(s) */
929 +       for (l = 0; l < old_lv->lv_allocated_le; l++) {
930 +               vg_ptr->pe_allocated--;
931 +               for (p = 0; p < vg_ptr->pv_cur; p++) {
932 +                       if (vg_ptr->pv[p]->pv_dev ==
933 +                           old_lv->lv_current_pe[l].dev) {
934 +                               vg_ptr->pv[p]->pe_allocated--;
935 +                               break;
936 +                       }
937 +               }
938 +       }
939  
940 -        /* allocate space for new pe structures */
941 -        size = new_lv->lv_current_le * sizeof(pe_t);
942 -        if ((pe = vmalloc(size)) == NULL) {
943 -                printk(KERN_CRIT
944 -                       "%s -- lvm_do_lv_extend_reduce: "
945 -                       "vmalloc error LV_CURRENT_PE of %lu Byte at line %d\n",
946 -                       lvm_name, size, __LINE__);
947 -                return -ENOMEM;
948 -        }
949 -
950 -        /* get the PE structures from user space */
951 -        if (copy_from_user(pe, new_lv->lv_current_pe, size)) {
952 -                if(old_lv->lv_access & LV_SNAPSHOT)
953 -                        vfree(new_lv->lv_snapshot_hash_table);
954 -                vfree(pe);
955 -                return -EFAULT;
956 -        }
957 -
958 -        new_lv->lv_current_pe = pe;
959 -
960 -        /* reduce allocation counters on PV(s) */
961 -        for (l = 0; l < old_lv->lv_allocated_le; l++) {
962 -                vg_ptr->pe_allocated--;
963 -                for (p = 0; p < vg_ptr->pv_cur; p++) {
964 -                        if (vg_ptr->pv[p]->pv_dev ==
965 -                            old_lv->lv_current_pe[l].dev) {
966 -                                vg_ptr->pv[p]->pe_allocated--;
967 -                                break;
968 -                        }
969 -                }
970 -        }
971 -
972 -        /* extend the PE count in PVs */
973 -        for (l = 0; l < new_lv->lv_allocated_le; l++) {
974 -                vg_ptr->pe_allocated++;
975 -                for (p = 0; p < vg_ptr->pv_cur; p++) {
976 -                        if (vg_ptr->pv[p]->pv_dev ==
977 +       /* extend the PE count in PVs */
978 +       for (l = 0; l < new_lv->lv_allocated_le; l++) {
979 +               vg_ptr->pe_allocated++;
980 +               for (p = 0; p < vg_ptr->pv_cur; p++) {
981 +                       if (vg_ptr->pv[p]->pv_dev ==
982                              new_lv->lv_current_pe[l].dev) {
983 -                                vg_ptr->pv[p]->pe_allocated++;
984 -                                break;
985 -                        }
986 -                }
987 -        }
988 -
989 -        /* save availiable i/o statistic data */
990 -        if (old_lv->lv_stripes < 2) {   /* linear logical volume */
991 -                end = min(old_lv->lv_current_le, new_lv->lv_current_le);
992 -                for (l = 0; l < end; l++) {
993 -                        new_lv->lv_current_pe[l].reads +=
994 -                                old_lv->lv_current_pe[l].reads;
995 -
996 -                        new_lv->lv_current_pe[l].writes +=
997 -                                old_lv->lv_current_pe[l].writes;
998 -                }
999 -
1000 -        } else {                /* striped logical volume */
1001 -                uint i, j, source, dest, end, old_stripe_size, new_stripe_size;
1002 -
1003 -                old_stripe_size = old_lv->lv_allocated_le / old_lv->lv_stripes;
1004 -                new_stripe_size = new_lv->lv_allocated_le / new_lv->lv_stripes;
1005 -                end = min(old_stripe_size, new_stripe_size);
1006 -
1007 -                for (i = source = dest = 0;
1008 -                     i < new_lv->lv_stripes; i++) {
1009 -                        for (j = 0; j < end; j++) {
1010 -                                new_lv->lv_current_pe[dest + j].reads +=
1011 -                                    old_lv->lv_current_pe[source + j].reads;
1012 -                                new_lv->lv_current_pe[dest + j].writes +=
1013 -                                    old_lv->lv_current_pe[source + j].writes;
1014 -                        }
1015 -                        source += old_stripe_size;
1016 -                        dest += new_stripe_size;
1017 -                }
1018 -        }
1019 +                               vg_ptr->pv[p]->pe_allocated++;
1020 +                               break;
1021 +                       }
1022 +               }
1023 +       }
1024  
1025 -        return 0;
1026 +       /* save availiable i/o statistic data */
1027 +       if (old_lv->lv_stripes < 2) {   /* linear logical volume */
1028 +               end = min(old_lv->lv_current_le, new_lv->lv_current_le);
1029 +               for (l = 0; l < end; l++) {
1030 +                       new_lv->lv_current_pe[l].reads +=
1031 +                               old_lv->lv_current_pe[l].reads;
1032 +
1033 +                       new_lv->lv_current_pe[l].writes +=
1034 +                               old_lv->lv_current_pe[l].writes;
1035 +               }
1036 +
1037 +       } else {                /* striped logical volume */
1038 +               uint i, j, source, dest, end, old_stripe_size, new_stripe_size;
1039 +
1040 +               old_stripe_size = old_lv->lv_allocated_le / old_lv->lv_stripes;
1041 +               new_stripe_size = new_lv->lv_allocated_le / new_lv->lv_stripes;
1042 +               end = min(old_stripe_size, new_stripe_size);
1043 +
1044 +               for (i = source = dest = 0; i < new_lv->lv_stripes; i++) {
1045 +                       for (j = 0; j < end; j++) {
1046 +                               new_lv->lv_current_pe[dest + j].reads +=
1047 +                                   old_lv->lv_current_pe[source + j].reads;
1048 +                               new_lv->lv_current_pe[dest + j].writes +=
1049 +                                   old_lv->lv_current_pe[source + j].writes;
1050 +                       }
1051 +                       source += old_stripe_size;
1052 +                       dest += new_stripe_size;
1053 +               }
1054 +       }
1055 +
1056 +       return 0;
1057  }
1058  
1059  static int lvm_do_lv_extend_reduce(int minor, char *lv_name, lv_t *new_lv)
1060  {
1061 -        int r;
1062 -        ulong l, e, size;
1063 -        vg_t *vg_ptr = vg[VG_CHR(minor)];
1064 -        lv_t *old_lv;
1065 -        pe_t *pe;
1066 -
1067 -        if ((pe = new_lv->lv_current_pe) == NULL)
1068 -                return -EINVAL;
1069 -
1070 -        for (l = 0; l < vg_ptr->lv_max; l++)
1071 -                if (vg_ptr->lv[l] && !strcmp(vg_ptr->lv[l]->lv_name, lv_name))
1072 -                        break;
1073 +       int r;
1074 +       ulong l, e, size;
1075 +       vg_t *vg_ptr = vg[VG_CHR(minor)];
1076 +       lv_t *old_lv;
1077 +       pe_t *pe;
1078  
1079 -        if (l == vg_ptr->lv_max)
1080 -                return -ENXIO;
1081 +       if ((pe = new_lv->lv_current_pe) == NULL)
1082 +               return -EINVAL;
1083  
1084 -        old_lv = vg_ptr->lv[l];
1085 +       for (l = 0; l < vg_ptr->lv_max; l++)
1086 +               if (vg_ptr->lv[l] && !strcmp(vg_ptr->lv[l]->lv_name, lv_name))
1087 +                       break;
1088 +
1089 +       if (l == vg_ptr->lv_max)
1090 +               return -ENXIO;
1091 +
1092 +       old_lv = vg_ptr->lv[l];
1093  
1094         if (old_lv->lv_access & LV_SNAPSHOT) {
1095                 /* only perform this operation on active snapshots */
1096                 if (old_lv->lv_status & LV_ACTIVE)
1097 -                r = __extend_reduce_snapshot(vg_ptr, old_lv, new_lv);
1098 -        else
1099 +                       r = __extend_reduce_snapshot(vg_ptr, old_lv, new_lv);
1100 +               else
1101                         r = -EPERM;
1102  
1103         } else
1104 -                r = __extend_reduce(vg_ptr, old_lv, new_lv);
1105 +               r = __extend_reduce(vg_ptr, old_lv, new_lv);
1106  
1107 -        if(r)
1108 -                return r;
1109 +       if(r)
1110 +               return r;
1111  
1112 -        /* copy relevent fields */
1113 +       /* copy relevent fields */
1114         down_write(&old_lv->lv_lock);
1115  
1116 -        if(new_lv->lv_access & LV_SNAPSHOT) {
1117 -                size = (new_lv->lv_remap_end > old_lv->lv_remap_end) ?
1118 -                        old_lv->lv_remap_ptr : new_lv->lv_remap_end;
1119 -                size *= sizeof(lv_block_exception_t);
1120 -                memcpy(new_lv->lv_block_exception,
1121 -                       old_lv->lv_block_exception, size);
1122 -
1123 -                old_lv->lv_remap_end = new_lv->lv_remap_end;
1124 -                old_lv->lv_block_exception = new_lv->lv_block_exception;
1125 -                old_lv->lv_snapshot_hash_table =
1126 -                        new_lv->lv_snapshot_hash_table;
1127 -                old_lv->lv_snapshot_hash_table_size =
1128 -                        new_lv->lv_snapshot_hash_table_size;
1129 -                old_lv->lv_snapshot_hash_mask =
1130 -                        new_lv->lv_snapshot_hash_mask;
1131 -
1132 -                for (e = 0; e < new_lv->lv_remap_ptr; e++)
1133 -                        lvm_hash_link(new_lv->lv_block_exception + e,
1134 -                                      new_lv->lv_block_exception[e].rdev_org,
1135 -                                    new_lv->lv_block_exception[e].rsector_org,
1136 -                                      new_lv);
1137 -
1138 -        } else {
1139 -
1140 -                vfree(old_lv->lv_current_pe);
1141 -                vfree(old_lv->lv_snapshot_hash_table);
1142 -
1143 -                old_lv->lv_size = new_lv->lv_size;
1144 -                old_lv->lv_allocated_le = new_lv->lv_allocated_le;
1145 -                old_lv->lv_current_le = new_lv->lv_current_le;
1146 -                old_lv->lv_current_pe = new_lv->lv_current_pe;
1147 -                lvm_gendisk.part[MINOR(old_lv->lv_dev)].nr_sects =
1148 -                        old_lv->lv_size;
1149 -                lvm_size[MINOR(old_lv->lv_dev)] = old_lv->lv_size >> 1;
1150 -
1151 -                if (old_lv->lv_access & LV_SNAPSHOT_ORG) {
1152 -                        lv_t *snap;
1153 -                        for(snap = old_lv->lv_snapshot_next; snap;
1154 -                            snap = snap->lv_snapshot_next) {
1155 +       if(new_lv->lv_access & LV_SNAPSHOT) {
1156 +               size = (new_lv->lv_remap_end > old_lv->lv_remap_end) ?
1157 +                       old_lv->lv_remap_ptr : new_lv->lv_remap_end;
1158 +               size *= sizeof(lv_block_exception_t);
1159 +               memcpy(new_lv->lv_block_exception,
1160 +                      old_lv->lv_block_exception, size);
1161 +
1162 +               old_lv->lv_remap_end = new_lv->lv_remap_end;
1163 +               old_lv->lv_block_exception = new_lv->lv_block_exception;
1164 +               old_lv->lv_snapshot_hash_table =
1165 +                       new_lv->lv_snapshot_hash_table;
1166 +               old_lv->lv_snapshot_hash_table_size =
1167 +                       new_lv->lv_snapshot_hash_table_size;
1168 +               old_lv->lv_snapshot_hash_mask =
1169 +                       new_lv->lv_snapshot_hash_mask;
1170 +
1171 +               for (e = 0; e < new_lv->lv_remap_ptr; e++)
1172 +                       lvm_hash_link(new_lv->lv_block_exception + e,
1173 +                                     new_lv->lv_block_exception[e].rdev_org,
1174 +                                     new_lv->lv_block_exception[e].rsector_org,
1175 +                                     new_lv);
1176 +
1177 +       } else {
1178 +
1179 +               vfree(old_lv->lv_current_pe);
1180 +               vfree(old_lv->lv_snapshot_hash_table);
1181 +
1182 +               old_lv->lv_size = new_lv->lv_size;
1183 +               old_lv->lv_allocated_le = new_lv->lv_allocated_le;
1184 +               old_lv->lv_current_le = new_lv->lv_current_le;
1185 +               old_lv->lv_current_pe = new_lv->lv_current_pe;
1186 +               lvm_gendisk.part[MINOR(old_lv->lv_dev)].nr_sects =
1187 +                       old_lv->lv_size;
1188 +               lvm_size[MINOR(old_lv->lv_dev)] = old_lv->lv_size >> 1;
1189 +
1190 +               if (old_lv->lv_access & LV_SNAPSHOT_ORG) {
1191 +                       lv_t *snap;
1192 +                       for(snap = old_lv->lv_snapshot_next; snap;
1193 +                           snap = snap->lv_snapshot_next) {
1194                                 down_write(&snap->lv_lock);
1195 -                                snap->lv_current_pe = old_lv->lv_current_pe;
1196 -                                snap->lv_allocated_le =
1197 -                                        old_lv->lv_allocated_le;
1198 -                                snap->lv_current_le = old_lv->lv_current_le;
1199 -                                snap->lv_size = old_lv->lv_size;
1200 -
1201 -                                lvm_gendisk.part[MINOR(snap->lv_dev)].nr_sects
1202 -                                        = old_lv->lv_size;
1203 -                                lvm_size[MINOR(snap->lv_dev)] =
1204 -                                        old_lv->lv_size >> 1;
1205 -                                __update_hardsectsize(snap);
1206 +                               snap->lv_current_pe = old_lv->lv_current_pe;
1207 +                               snap->lv_allocated_le =
1208 +                                       old_lv->lv_allocated_le;
1209 +                               snap->lv_current_le = old_lv->lv_current_le;
1210 +                               snap->lv_size = old_lv->lv_size;
1211 +
1212 +                               lvm_gendisk.part[MINOR(snap->lv_dev)].nr_sects
1213 +                                       = old_lv->lv_size;
1214 +                               lvm_size[MINOR(snap->lv_dev)] =
1215 +                                       old_lv->lv_size >> 1;
1216 +                               __update_hardsectsize(snap);
1217                                 up_write(&snap->lv_lock);
1218 -                        }
1219 -                }
1220 -        }
1221 +                       }
1222 +               }
1223 +       }
1224  
1225 -        __update_hardsectsize(old_lv);
1226 +       __update_hardsectsize(old_lv);
1227         up_write(&old_lv->lv_lock);
1228  
1229 -        return 0;
1230 +       return 0;
1231  } /* lvm_do_lv_extend_reduce() */
1232  
1233  
1234 @@ -2426,7 +2501,6 @@
1235                                          lv_ptr,
1236                                          sizeof(lv_t)) != 0)
1237                                 return -EFAULT;
1238 -
1239                         if (saved_ptr1 != NULL) {
1240                                 if (copy_to_user(saved_ptr1,
1241                                                  lv_ptr->lv_current_pe,
1242 @@ -2461,9 +2535,6 @@
1243  
1244         if (lv_status_byindex_req.lv == NULL)
1245                 return -EINVAL;
1246 -       if (lv_status_byindex_req.lv_index <0 ||
1247 -               lv_status_byindex_req.lv_index >= MAX_LV)
1248 -               return -EINVAL;
1249         if ( ( lv_ptr = vg_ptr->lv[lv_status_byindex_req.lv_index]) == NULL)
1250                 return -ENXIO;
1251  
1252 @@ -2552,9 +2623,7 @@
1253                 if (lv_ptr->lv_dev == lv->lv_dev)
1254                 {
1255                         lvm_fs_remove_lv(vg_ptr, lv_ptr);
1256 -                       strncpy(lv_ptr->lv_name,
1257 -                               lv_req->lv_name,
1258 -                               NAME_LEN);
1259 +                       strncpy(lv_ptr->lv_name, lv_req->lv_name, NAME_LEN);
1260                         lvm_fs_create_lv(vg_ptr, lv_ptr);
1261                         break;
1262                 }
1263 @@ -2629,23 +2698,24 @@
1264         return -ENXIO;
1265  } /* lvm_do_pv_status() */
1266  
1267 +
1268  /*
1269   * character device support function flush and invalidate all buffers of a PV
1270   */
1271  static int lvm_do_pv_flush(void *arg)
1272  {
1273 -       pv_flush_req_t pv_flush_req;
1274 +       pv_flush_req_t pv_flush_req;
1275  
1276 -       if (copy_from_user(&pv_flush_req, arg,
1277 -                          sizeof(pv_flush_req)) != 0)
1278 -               return -EFAULT;
1279 +       if (copy_from_user(&pv_flush_req, arg, sizeof(pv_flush_req)) != 0)
1280 +               return -EFAULT;
1281  
1282 -       fsync_dev(pv_flush_req.pv_dev);
1283 -       invalidate_buffers(pv_flush_req.pv_dev);
1284 +       fsync_dev(pv_flush_req.pv_dev);
1285 +       invalidate_buffers(pv_flush_req.pv_dev);
1286  
1287 -       return 0;
1288 +       return 0;
1289  }
1290  
1291 +
1292  /*
1293   * support function initialize gendisk variables
1294   */
1295 @@ -2708,6 +2778,7 @@
1296         }
1297  }
1298  
1299 +
1300  /*
1301   * we must open the pv's before we use them
1302   */
1303 @@ -2719,22 +2790,25 @@
1304                 return -ENOMEM;
1305  
1306         err = blkdev_get(bd, FMODE_READ|FMODE_WRITE, 0, BDEV_FILE);
1307 -       if (err)
1308 +       if (err) {
1309 +               bdput(bd);
1310                 return err;
1311 +       }
1312  
1313         pv->bd = bd;
1314         return 0;
1315  }
1316  
1317  static void _close_pv(pv_t *pv) {
1318 -       if (pv) {
1319 -               struct block_device *bdev = pv->bd;
1320 -               pv->bd = NULL;
1321 -               if (bdev)
1322 -                       blkdev_put(bdev, BDEV_FILE);
1323 -       }
1324 +       if(!pv || !pv->bd)
1325 +               return;
1326 +
1327 +       blkdev_put(pv->bd, BDEV_FILE);
1328 +       bdput(pv->bd);
1329 +       pv->bd = 0;
1330  }
1331  
1332 +
1333  static unsigned long _sectors_to_k(unsigned long sect)
1334  {
1335         if(SECTOR_SIZE > 1024) {
1336 @@ -2744,6 +2818,11 @@
1337         return sect / (1024 / SECTOR_SIZE);
1338  }
1339  
1340 +MODULE_AUTHOR("Heinz Mauelshagen, Sistina Software");
1341 +MODULE_DESCRIPTION("Logical Volume Manager");
1342 +#ifdef MODULE_LICENSE
1343 +MODULE_LICENSE("GPL");
1344 +#endif
1345 +
1346  module_init(lvm_init);
1347  module_exit(lvm_cleanup);
1348 -MODULE_LICENSE("GPL");
1349 --- linux/drivers/md/lvm-internal.h.orig        Sun Nov 11 18:09:32 2001
1350 +++ linux/drivers/md/lvm-internal.h     Thu Jan 10 12:24:08 2002
1351 @@ -1,5 +1,6 @@
1352 +
1353  /*
1354 - * kernel/lvm-internal.h
1355 + * kernel/lvm_internal.h
1356   *
1357   * Copyright (C) 2001 Sistina Software
1358   *
1359 @@ -24,7 +25,9 @@
1360  /*
1361   * Changelog
1362   *
1363 - *    05/01/2001:Joe Thornber - Factored this file out of lvm.c
1364 + *    05/01/2001 - Factored this file out of lvm.c (Joe Thornber)
1365 + *    11/01/2001 - Renamed lvm_internal and added declarations
1366 + *                 for lvm_fs.c stuff
1367   *
1368   */
1369  
1370 @@ -33,7 +36,7 @@
1371  
1372  #include <linux/lvm.h>
1373  
1374 -#define _LVM_INTERNAL_H_VERSION "LVM "LVM_RELEASE_NAME" ("LVM_RELEASE_DATE")"
1375 +#define        _LVM_INTERNAL_H_VERSION "LVM "LVM_RELEASE_NAME" ("LVM_RELEASE_DATE")"
1376  
1377  /* global variables, defined in lvm.c */
1378  extern char *lvm_version;
1379 @@ -42,11 +45,15 @@
1380  extern const char *const lvm_name;
1381  
1382  
1383 +extern uint vg_count;
1384  extern vg_t *vg[];
1385  extern struct file_operations lvm_chr_fops;
1386  
1387  extern struct block_device_operations lvm_blk_dops;
1388  
1389 +#define lvm_sectsize(dev) get_hardsect_size(dev)
1390 +
1391 +/* 2.4.8 had no global min/max macros, and 2.4.9's were flawed */
1392  
1393  /* debug macros */
1394  #ifdef DEBUG_IOCTL
1395 --- linux/drivers/md/lvm-snap.c.orig    Fri Dec 21 17:41:54 2001
1396 +++ linux/drivers/md/lvm-snap.c Thu Jan 10 12:24:08 2002
1397 @@ -2,22 +2,22 @@
1398   * kernel/lvm-snap.c
1399   *
1400   * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
1401 - *                    Heinz Mauelshagen, Sistina Software (persistent snapshots)
1402 + *               2000 - 2001 Heinz Mauelshagen, Sistina Software
1403   *
1404   * LVM snapshot driver is free software; you can redistribute it and/or modify
1405   * it under the terms of the GNU General Public License as published by
1406   * the Free Software Foundation; either version 2, or (at your option)
1407   * any later version.
1408 - * 
1409 + *
1410   * LVM snapshot driver is distributed in the hope that it will be useful,
1411   * but WITHOUT ANY WARRANTY; without even the implied warranty of
1412   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1413   * GNU General Public License for more details.
1414 - * 
1415 + *
1416   * You should have received a copy of the GNU General Public License
1417   * along with GNU CC; see the file COPYING.  If not, write to
1418   * the Free Software Foundation, 59 Temple Place - Suite 330,
1419 - * Boston, MA 02111-1307, USA. 
1420 + * Boston, MA 02111-1307, USA.
1421   *
1422   */
1423  
1424 @@ -28,52 +28,66 @@
1425   *    23/11/2000 - used cpu_to_le64 rather than my own macro
1426   *    25/01/2001 - Put LockPage back in
1427   *    01/02/2001 - A dropped snapshot is now set as inactive
1428 + *    14/02/2001 - tidied debug statements
1429 + *    19/02/2001 - changed rawio calls to pass in preallocated buffer_heads
1430 + *    26/02/2001 - introduced __brw_kiovec to remove a lot of conditional
1431 + *                 compiles.
1432 + *    07/03/2001 - fixed COW exception table not persistent on 2.2 (HM)
1433   *    12/03/2001 - lvm_pv_get_number changes:
1434   *                 o made it static
1435   *                 o renamed it to _pv_get_number
1436   *                 o pv number is returned in new uint * arg
1437   *                 o -1 returned on error
1438   *                 lvm_snapshot_fill_COW_table has a return value too.
1439 + *    15/10/2001 - fix snapshot alignment problem [CM]
1440 + *               - fix snapshot full oops (always check lv_block_exception) [CM]
1441   *
1442   */
1443  
1444  #include <linux/kernel.h>
1445 -#include <linux/module.h>
1446  #include <linux/vmalloc.h>
1447  #include <linux/blkdev.h>
1448  #include <linux/smp_lock.h>
1449  #include <linux/types.h>
1450  #include <linux/iobuf.h>
1451  #include <linux/lvm.h>
1452 +#include <linux/devfs_fs_kernel.h>
1453  
1454  
1455  #include "lvm-internal.h"
1456  
1457 -static char *lvm_snap_version __attribute__ ((unused)) =
1458 -   "LVM "LVM_RELEASE_NAME" snapshot code ("LVM_RELEASE_DATE")\n";
1459 +static char *lvm_snap_version __attribute__ ((unused)) = "LVM "LVM_RELEASE_NAME" snapshot code ("LVM_RELEASE_DATE")\n";
1460  
1461  
1462  extern const char *const lvm_name;
1463  extern int lvm_blocksizes[];
1464  
1465  void lvm_snapshot_release(lv_t *);
1466 +
1467  static int _write_COW_table_block(vg_t *vg, lv_t *lv, int idx,
1468 -                                 const char **reason);
1469 +                                 const char **reason);
1470  static void _disable_snapshot(vg_t *vg, lv_t *lv);
1471  
1472  
1473 -static int _pv_get_number(vg_t * vg, kdev_t rdev, uint *pvn) {
1474 +static inline int __brw_kiovec(int rw, int nr, struct kiobuf *iovec[],
1475 +                              kdev_t dev, unsigned long b[], int size,
1476 +                              lv_t *lv) {
1477 +       return brw_kiovec(rw, nr, iovec, dev, b, size);
1478 +}
1479 +
1480 +
1481 +static int _pv_get_number(vg_t * vg, kdev_t rdev, uint *pvn)
1482 +{
1483         uint p;
1484 -       for(p = 0; p < vg->pv_max; p++) {
1485 -               if(vg->pv[p] == NULL)
1486 +       for (p = 0; p < vg->pv_max; p++) {
1487 +               if (vg->pv[p] == NULL)
1488                         continue;
1489  
1490 -               if(vg->pv[p]->pv_dev == rdev)
1491 +               if (vg->pv[p]->pv_dev == rdev)
1492                         break;
1493 -
1494         }
1495  
1496 -       if(p >= vg->pv_max) {
1497 +       if (p >= vg->pv_max) {
1498                 /* bad news, the snapshot COW table is probably corrupt */
1499                 printk(KERN_ERR
1500                        "%s -- _pv_get_number failed for rdev = %u\n",
1501 @@ -85,6 +99,7 @@
1502         return 0;
1503  }
1504  
1505 +
1506  #define hashfn(dev,block,mask,chunk_size) \
1507         ((HASHDEV(dev)^((block)/(chunk_size))) & (mask))
1508  
1509 @@ -129,10 +144,20 @@
1510         unsigned long mask = lv->lv_snapshot_hash_mask;
1511         int chunk_size = lv->lv_chunk_size;
1512  
1513 +       if (!hash_table)
1514 +               BUG();
1515         hash_table = &hash_table[hashfn(org_dev, org_start, mask, chunk_size)];
1516         list_add(&exception->hash, hash_table);
1517  }
1518  
1519 +/*
1520 + * Determine if we already have a snapshot chunk for this block.
1521 + * Return: 1 if it the chunk already exists
1522 + *         0 if we need to COW this block and allocate a new chunk
1523 + *        -1 if the snapshot was disabled because it ran out of space
1524 + *
1525 + * We need to be holding at least a read lock on lv->lv_lock.
1526 + */
1527  int lvm_snapshot_remap_block(kdev_t * org_dev, unsigned long * org_sector,
1528                              unsigned long pe_start, lv_t * lv)
1529  {
1530 @@ -142,6 +167,9 @@
1531         int chunk_size = lv->lv_chunk_size;
1532         lv_block_exception_t * exception;
1533  
1534 +       if (!lv->lv_block_exception)
1535 +               return -1;
1536 +
1537         pe_off = pe_start % chunk_size;
1538         pe_adjustment = (*org_sector-pe_off) % chunk_size;
1539         __org_start = *org_sector - pe_adjustment;
1540 @@ -166,8 +194,8 @@
1541            or error on this snapshot --> release it */
1542         invalidate_buffers(lv_snap->lv_dev);
1543  
1544 -       /* wipe the snapshot since it's inconsistent now */
1545 -       _disable_snapshot(vg, lv_snap);
1546 +       /* wipe the snapshot since it's inconsistent now */
1547 +       _disable_snapshot(vg, lv_snap);
1548  
1549         for (i = last_dev = 0; i < lv_snap->lv_remap_ptr; i++) {
1550                 if ( lv_snap->lv_block_exception[i].rdev_new != last_dev) {
1551 @@ -186,15 +214,15 @@
1552  }
1553  
1554  static inline int lvm_snapshot_prepare_blocks(unsigned long *blocks,
1555 -                                             unsigned long start,
1556 -                                             int nr_sectors,
1557 -                                             int blocksize)
1558 +                                              unsigned long start,
1559 +                                              int nr_sectors,
1560 +                                              int blocksize)
1561  {
1562         int i, sectors_per_block, nr_blocks;
1563  
1564         sectors_per_block = blocksize / SECTOR_SIZE;
1565  
1566 -       if(start & (sectors_per_block - 1))
1567 +       if (start & (sectors_per_block - 1))
1568                 return 0;
1569  
1570         nr_blocks = nr_sectors / sectors_per_block;
1571 @@ -245,49 +273,51 @@
1572  
1573  int lvm_snapshot_fill_COW_page(vg_t * vg, lv_t * lv_snap)
1574  {
1575 -       uint pvn;
1576 -       int id = 0, is = lv_snap->lv_remap_ptr;
1577 -       ulong blksize_snap;
1578 -       lv_COW_table_disk_t * lv_COW_table = (lv_COW_table_disk_t *)
1579 -               page_address(lv_snap->lv_COW_table_iobuf->maplist[0]);
1580 +       int id = 0, is = lv_snap->lv_remap_ptr;
1581 +       ulong blksize_snap;
1582 +       lv_COW_table_disk_t * lv_COW_table = (lv_COW_table_disk_t *)
1583 +               page_address(lv_snap->lv_COW_table_iobuf->maplist[0]);
1584  
1585 -       if (is == 0)
1586 -               return 0;
1587 +       if (is == 0)
1588 +               return 0;
1589  
1590         is--;
1591 -        blksize_snap =
1592 -               lvm_get_blksize(lv_snap->lv_block_exception[is].rdev_new);
1593 -        is -= is % (blksize_snap / sizeof(lv_COW_table_disk_t));
1594 +       blksize_snap =
1595 +               lvm_get_blksize(lv_snap->lv_block_exception[is].rdev_new);
1596 +       is -= is % (blksize_snap / sizeof(lv_COW_table_disk_t));
1597  
1598         memset(lv_COW_table, 0, blksize_snap);
1599         for ( ; is < lv_snap->lv_remap_ptr; is++, id++) {
1600                 /* store new COW_table entry */
1601 -               lv_block_exception_t *be = lv_snap->lv_block_exception + is;
1602 -               if(_pv_get_number(vg, be->rdev_org, &pvn))
1603 -                       goto bad;
1604 +               lv_block_exception_t *be = lv_snap->lv_block_exception + is;
1605 +               uint pvn;
1606  
1607 -               lv_COW_table[id].pv_org_number = cpu_to_le64(pvn);
1608 -               lv_COW_table[id].pv_org_rsector = cpu_to_le64(be->rsector_org);
1609 -               if(_pv_get_number(vg, be->rdev_new, &pvn))
1610 -                       goto bad;
1611 +               if (_pv_get_number(vg, be->rdev_org, &pvn))
1612 +                       goto bad;
1613  
1614 -               lv_COW_table[id].pv_snap_number = cpu_to_le64(pvn);
1615 -               lv_COW_table[id].pv_snap_rsector =
1616 -                       cpu_to_le64(be->rsector_new);
1617 +               lv_COW_table[id].pv_org_number = cpu_to_le64(pvn);
1618 +               lv_COW_table[id].pv_org_rsector = cpu_to_le64(be->rsector_org);
1619 +
1620 +               if (_pv_get_number(vg, be->rdev_new, &pvn))
1621 +                       goto bad;
1622 +
1623 +               lv_COW_table[id].pv_snap_number = cpu_to_le64(pvn);
1624 +               lv_COW_table[id].pv_snap_rsector = cpu_to_le64(be->rsector_new);
1625         }
1626  
1627 -       return 0;
1628 +       return 0;
1629  
1630   bad:
1631 -       printk(KERN_ERR "%s -- lvm_snapshot_fill_COW_page failed", lvm_name);
1632 -       return -1;
1633 +       printk(KERN_ERR "%s -- lvm_snapshot_fill_COW_page failed", lvm_name);
1634 +       return -1;
1635  }
1636  
1637  
1638  /*
1639   * writes a COW exception table sector to disk (HM)
1640 + *
1641 + * We need to hold a write lock on lv_snap->lv_lock.
1642   */
1643 -
1644  int lvm_write_COW_table_block(vg_t * vg, lv_t *lv_snap)
1645  {
1646         int r;
1647 @@ -305,6 +335,10 @@
1648   * if there is no exception storage space free any longer --> release snapshot.
1649   *
1650   * this routine gets called for each _first_ write to a physical chunk.
1651 + *
1652 + * We need to hold a write lock on lv_snap->lv_lock.  It is assumed that
1653 + * lv->lv_block_exception is non-NULL (checked by lvm_snapshot_remap_block())
1654 + * when this function is called.
1655   */
1656  int lvm_snapshot_COW(kdev_t org_phys_dev,
1657                      unsigned long org_phys_sector,
1658 @@ -314,8 +348,10 @@
1659  {
1660         const char * reason;
1661         unsigned long org_start, snap_start, snap_phys_dev, virt_start, pe_off;
1662 +       unsigned long phys_start;
1663         int idx = lv_snap->lv_remap_ptr, chunk_size = lv_snap->lv_chunk_size;
1664         struct kiobuf * iobuf;
1665 +       unsigned long blocks[KIO_MAX_SECTORS];
1666         int blksize_snap, blksize_org, min_blksize, max_blksize;
1667         int max_sectors, nr_sectors;
1668  
1669 @@ -347,8 +383,8 @@
1670  
1671         iobuf = lv_snap->lv_iobuf;
1672  
1673 -       blksize_org = lvm_get_blksize(org_phys_dev);
1674 -       blksize_snap = lvm_get_blksize(snap_phys_dev);
1675 +       blksize_org = lvm_sectsize(org_phys_dev);
1676 +       blksize_snap = lvm_sectsize(snap_phys_dev);
1677         max_blksize = max(blksize_org, blksize_snap);
1678         min_blksize = min(blksize_org, blksize_snap);
1679         max_sectors = KIO_MAX_SECTORS * (min_blksize>>9);
1680 @@ -356,6 +392,9 @@
1681         if (chunk_size % (max_blksize>>9))
1682                 goto fail_blksize;
1683  
1684 +       /* Don't change org_start, we need it to fill in the exception table */
1685 +       phys_start = org_start;
1686 +
1687         while (chunk_size)
1688         {
1689                 nr_sectors = min(chunk_size, max_sectors);
1690 @@ -363,21 +402,24 @@
1691  
1692                 iobuf->length = nr_sectors << 9;
1693  
1694 -               if(!lvm_snapshot_prepare_blocks(iobuf->blocks, org_start,
1695 -                                               nr_sectors, blksize_org))
1696 +               if (!lvm_snapshot_prepare_blocks(blocks, phys_start,
1697 +                                                nr_sectors, blksize_org))
1698                         goto fail_prepare;
1699  
1700 -               if (brw_kiovec(READ, 1, &iobuf, org_phys_dev,
1701 -                              iobuf->blocks, blksize_org) != (nr_sectors<<9))
1702 +               if (__brw_kiovec(READ, 1, &iobuf, org_phys_dev, blocks,
1703 +                                blksize_org, lv_snap) != (nr_sectors<<9))
1704                         goto fail_raw_read;
1705  
1706 -               if(!lvm_snapshot_prepare_blocks(iobuf->blocks, snap_start,
1707 -                                               nr_sectors, blksize_snap))
1708 +               if (!lvm_snapshot_prepare_blocks(blocks, snap_start,
1709 +                                                nr_sectors, blksize_snap))
1710                         goto fail_prepare;
1711  
1712 -               if (brw_kiovec(WRITE, 1, &iobuf, snap_phys_dev,
1713 -                              iobuf->blocks, blksize_snap) != (nr_sectors<<9))
1714 +               if (__brw_kiovec(WRITE, 1, &iobuf, snap_phys_dev, blocks,
1715 +                                blksize_snap, lv_snap) != (nr_sectors<<9))
1716                         goto fail_raw_write;
1717 +
1718 +               phys_start += nr_sectors;
1719 +               snap_start += nr_sectors;
1720         }
1721  
1722  #ifdef DEBUG_SNAPSHOT
1723 @@ -401,24 +443,24 @@
1724         return 0;
1725  
1726         /* slow path */
1727 - out:
1728 +out:
1729         lvm_drop_snapshot(vg, lv_snap, reason);
1730         return 1;
1731  
1732 - fail_out_of_space:
1733 +fail_out_of_space:
1734         reason = "out of space";
1735         goto out;
1736 - fail_raw_read:
1737 +fail_raw_read:
1738         reason = "read error";
1739         goto out;
1740 - fail_raw_write:
1741 +fail_raw_write:
1742         reason = "write error";
1743         goto out;
1744 - fail_blksize:
1745 +fail_blksize:
1746         reason = "blocksize error";
1747         goto out;
1748  
1749 - fail_prepare:
1750 +fail_prepare:
1751         reason = "couldn't prepare kiovec blocks "
1752                 "(start probably isn't block aligned)";
1753         goto out;
1754 @@ -441,8 +483,7 @@
1755                 struct page * page;
1756  
1757                 page = alloc_page(GFP_KERNEL);
1758 -               if (!page)
1759 -                       goto out;
1760 +               if (!page) goto out;
1761  
1762                 iobuf->maplist[i] = page;
1763                 LockPage(page);
1764 @@ -451,7 +492,8 @@
1765         iobuf->offset = 0;
1766  
1767         err = 0;
1768 - out:
1769 +
1770 +out:
1771         return err;
1772  }
1773  
1774 @@ -515,13 +557,12 @@
1775         if (ret) goto out_free_kiovec;
1776  
1777         ret = lvm_snapshot_alloc_iobuf_pages(lv_snap->lv_COW_table_iobuf,
1778 -                                            PAGE_SIZE/SECTOR_SIZE);
1779 +                                            PAGE_SIZE/SECTOR_SIZE);
1780         if (ret) goto out_free_both_kiovecs;
1781  
1782         ret = lvm_snapshot_alloc_hash_table(lv_snap);
1783         if (ret) goto out_free_both_kiovecs;
1784  
1785 -
1786  out:
1787         return ret;
1788  
1789 @@ -534,8 +575,7 @@
1790         unmap_kiobuf(lv_snap->lv_iobuf);
1791         free_kiovec(1, &lv_snap->lv_iobuf);
1792         lv_snap->lv_iobuf = NULL;
1793 -       if (lv_snap->lv_snapshot_hash_table != NULL)
1794 -               vfree(lv_snap->lv_snapshot_hash_table);
1795 +       vfree(lv_snap->lv_snapshot_hash_table);
1796         lv_snap->lv_snapshot_hash_table = NULL;
1797         goto out;
1798  }
1799 @@ -562,10 +602,10 @@
1800         }
1801         if (lv->lv_COW_table_iobuf)
1802         {
1803 -               kiobuf_wait_for_io(lv->lv_COW_table_iobuf);
1804 -               unmap_kiobuf(lv->lv_COW_table_iobuf);
1805 -               free_kiovec(1, &lv->lv_COW_table_iobuf);
1806 -               lv->lv_COW_table_iobuf = NULL;
1807 +               kiobuf_wait_for_io(lv->lv_COW_table_iobuf);
1808 +               unmap_kiobuf(lv->lv_COW_table_iobuf);
1809 +               free_kiovec(1, &lv->lv_COW_table_iobuf);
1810 +               lv->lv_COW_table_iobuf = NULL;
1811         }
1812  }
1813  
1814 @@ -577,11 +617,11 @@
1815         int idx_COW_table;
1816         uint pvn;
1817         ulong snap_pe_start, COW_table_sector_offset,
1818 -               COW_entries_per_pe, COW_chunks_per_pe, COW_entries_per_block;
1819 +             COW_entries_per_pe, COW_chunks_per_pe, COW_entries_per_block;
1820         ulong blocks[1];
1821         kdev_t snap_phys_dev;
1822         lv_block_exception_t *be;
1823 -       struct kiobuf * COW_table_iobuf = lv_snap->lv_COW_table_iobuf;
1824 +       struct kiobuf *COW_table_iobuf = lv_snap->lv_COW_table_iobuf;
1825         lv_COW_table_disk_t * lv_COW_table =
1826            ( lv_COW_table_disk_t *) page_address(lv_snap->lv_COW_table_iobuf->maplist[0]);
1827  
1828 @@ -592,46 +632,47 @@
1829         snap_phys_dev = lv_snap->lv_block_exception[idx].rdev_new;
1830         snap_pe_start = lv_snap->lv_block_exception[idx - (idx % COW_entries_per_pe)].rsector_new - lv_snap->lv_chunk_size;
1831  
1832 -       blksize_snap = lvm_get_blksize(snap_phys_dev);
1833 +       blksize_snap = lvm_sectsize(snap_phys_dev);
1834  
1835          COW_entries_per_block = blksize_snap / sizeof(lv_COW_table_disk_t);
1836          idx_COW_table = idx % COW_entries_per_pe % COW_entries_per_block;
1837  
1838         if ( idx_COW_table == 0) memset(lv_COW_table, 0, blksize_snap);
1839  
1840 -       /* sector offset into the on disk COW table */
1841 +       /* sector offset into the on disk COW table */
1842         COW_table_sector_offset = (idx % COW_entries_per_pe) / (SECTOR_SIZE / sizeof(lv_COW_table_disk_t));
1843  
1844          /* COW table block to write next */
1845         blocks[0] = (snap_pe_start + COW_table_sector_offset) >> (blksize_snap >> 10);
1846  
1847         /* store new COW_table entry */
1848 -       be = lv_snap->lv_block_exception + idx;
1849 -       if(_pv_get_number(vg, be->rdev_org, &pvn))
1850 -               goto fail_pv_get_number;
1851 -
1852 -       lv_COW_table[idx_COW_table].pv_org_number = cpu_to_le64(pvn);
1853 -       lv_COW_table[idx_COW_table].pv_org_rsector =
1854 -               cpu_to_le64(be->rsector_org);
1855 -       if(_pv_get_number(vg, snap_phys_dev, &pvn))
1856 -               goto fail_pv_get_number;
1857 -
1858 -       lv_COW_table[idx_COW_table].pv_snap_number = cpu_to_le64(pvn);
1859 -       lv_COW_table[idx_COW_table].pv_snap_rsector =
1860 -               cpu_to_le64(be->rsector_new);
1861 +       be = lv_snap->lv_block_exception + idx;
1862 +       if(_pv_get_number(vg, be->rdev_org, &pvn))
1863 +               goto fail_pv_get_number;
1864 +
1865 +       lv_COW_table[idx_COW_table].pv_org_number = cpu_to_le64(pvn);
1866 +       lv_COW_table[idx_COW_table].pv_org_rsector =
1867 +               cpu_to_le64(be->rsector_org);
1868 +       if(_pv_get_number(vg, snap_phys_dev, &pvn))
1869 +               goto fail_pv_get_number;
1870 +
1871 +       lv_COW_table[idx_COW_table].pv_snap_number = cpu_to_le64(pvn);
1872 +       lv_COW_table[idx_COW_table].pv_snap_rsector =
1873 +               cpu_to_le64(be->rsector_new);
1874  
1875         COW_table_iobuf->length = blksize_snap;
1876 +       /* COW_table_iobuf->nr_pages = 1; */
1877  
1878 -       if (brw_kiovec(WRITE, 1, &COW_table_iobuf, snap_phys_dev,
1879 -                      blocks, blksize_snap) != blksize_snap)
1880 +       if (__brw_kiovec(WRITE, 1, &COW_table_iobuf, snap_phys_dev,
1881 +                        blocks, blksize_snap, lv_snap) != blksize_snap)
1882                 goto fail_raw_write;
1883  
1884 -       /* initialization of next COW exception table block with zeroes */
1885 +       /* initialization of next COW exception table block with zeroes */
1886         end_of_table = idx % COW_entries_per_pe == COW_entries_per_pe - 1;
1887         if (idx_COW_table % COW_entries_per_block == COW_entries_per_block - 1 || end_of_table)
1888         {
1889                 /* don't go beyond the end */
1890 -               if (idx + 1 >= lv_snap->lv_remap_end) goto out;
1891 +               if (idx + 1 >= lv_snap->lv_remap_end) goto out;
1892  
1893                 memset(lv_COW_table, 0, blksize_snap);
1894  
1895 @@ -640,24 +681,24 @@
1896                         idx++;
1897                         snap_phys_dev = lv_snap->lv_block_exception[idx].rdev_new;
1898                         snap_pe_start = lv_snap->lv_block_exception[idx - (idx % COW_entries_per_pe)].rsector_new - lv_snap->lv_chunk_size;
1899 -                       blksize_snap = lvm_get_blksize(snap_phys_dev);
1900 +                       blksize_snap = lvm_sectsize(snap_phys_dev);
1901                         blocks[0] = snap_pe_start >> (blksize_snap >> 10);
1902                 } else blocks[0]++;
1903  
1904 -               if (brw_kiovec(WRITE, 1, &COW_table_iobuf, snap_phys_dev,
1905 -                                 blocks, blksize_snap) !=
1906 +               if (__brw_kiovec(WRITE, 1, &COW_table_iobuf, snap_phys_dev,
1907 +                                 blocks, blksize_snap, lv_snap) !=
1908                      blksize_snap)
1909                         goto fail_raw_write;
1910         }
1911  
1912 - out:
1913 +out:
1914         return 0;
1915  
1916 - fail_raw_write:
1917 +fail_raw_write:
1918         *reason = "write error";
1919         return 1;
1920  
1921 - fail_pv_get_number:
1922 +fail_pv_get_number:
1923         *reason = "_pv_get_number failed";
1924         return 1;
1925  }
1926 @@ -681,5 +722,3 @@
1927                        lvm_name, err);
1928         }
1929  }
1930 -
1931 -MODULE_LICENSE("GPL");
1932 --- linux/drivers/md/lvm-fs.c.orig      Fri Dec 21 17:41:54 2001
1933 +++ linux/drivers/md/lvm-fs.c   Thu Jan 10 12:24:08 2002
1934 @@ -3,7 +3,7 @@
1935   *
1936   * Copyright (C) 2001 Sistina Software
1937   *
1938 - * January,February 2001
1939 + * January-April 2001
1940   *
1941   * LVM driver is free software; you can redistribute it and/or modify
1942   * it under the terms of the GNU General Public License as published by
1943 @@ -30,13 +30,11 @@
1944   *    04/10/2001 - corrected devfs_register() call in lvm_init_fs()
1945   *    11/04/2001 - don't devfs_register("lvm") as user-space always does it
1946   *    10/05/2001 - show more of PV name in /proc/lvm/global
1947 - *    16/12/2001 - fix devfs unregister order and prevent duplicate unreg (REG)
1948   *
1949   */
1950  
1951  #include <linux/config.h>
1952  #include <linux/version.h>
1953 -#include <linux/module.h>
1954  
1955  #include <linux/kernel.h>
1956  #include <linux/vmalloc.h>
1957 @@ -88,7 +86,6 @@
1958                 S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
1959                 &lvm_chr_fops, NULL);
1960  #endif
1961 -
1962         lvm_proc_dir = create_proc_entry(LVM_DIR, S_IFDIR, &proc_root);
1963         if (lvm_proc_dir) {
1964                 lvm_proc_vg_subdir = create_proc_entry(LVM_VG_SUBDIR, S_IFDIR,
1965 @@ -102,7 +99,6 @@
1966  #if 0
1967         devfs_unregister (lvm_devfs_handle);
1968  #endif
1969 -
1970         remove_proc_entry(LVM_GLOBAL, lvm_proc_dir);
1971         remove_proc_entry(LVM_VG_SUBDIR, lvm_proc_dir);
1972         remove_proc_entry(LVM_DIR, &proc_root);
1973 @@ -139,7 +135,7 @@
1974         int i;
1975  
1976         devfs_unregister(ch_devfs_handle[vg_ptr->vg_number]);
1977 -       ch_devfs_handle[vg_ptr->vg_number] = NULL;
1978 +       devfs_unregister(vg_devfs_handle[vg_ptr->vg_number]);
1979  
1980         /* remove lv's */
1981         for(i = 0; i < vg_ptr->lv_max; i++)
1982 @@ -149,10 +145,6 @@
1983         for(i = 0; i < vg_ptr->pv_max; i++)
1984                 if(vg_ptr->pv[i]) lvm_fs_remove_pv(vg_ptr, vg_ptr->pv[i]);
1985  
1986 -       /* must not remove directory before leaf nodes */
1987 -       devfs_unregister(vg_devfs_handle[vg_ptr->vg_number]);
1988 -       vg_devfs_handle[vg_ptr->vg_number] = NULL;
1989 -
1990         if(vg_ptr->vg_dir_pde) {
1991                 remove_proc_entry(LVM_LV_SUBDIR, vg_ptr->vg_dir_pde);
1992                 vg_ptr->lv_subdir_pde = NULL;
1993 @@ -194,7 +186,6 @@
1994  
1995  void lvm_fs_remove_lv(vg_t *vg_ptr, lv_t *lv) {
1996         devfs_unregister(lv_devfs_handle[MINOR(lv->lv_dev)]);
1997 -       lv_devfs_handle[MINOR(lv->lv_dev)] = NULL;
1998  
1999         if(vg_ptr->lv_subdir_pde) {
2000                 const char *name = _basename(lv->lv_name);
2001 @@ -282,12 +273,12 @@
2002         sz += sprintf(page + sz, "number:       %u\n", lv->lv_number);
2003         sz += sprintf(page + sz, "open:         %u\n", lv->lv_open);
2004         sz += sprintf(page + sz, "allocation:   %u\n", lv->lv_allocation);
2005 -       if(lv->lv_stripes > 1) {
2006 -               sz += sprintf(page + sz, "stripes:      %u\n",
2007 -                             lv->lv_stripes);
2008 -               sz += sprintf(page + sz, "stripesize:   %u\n",
2009 -                             lv->lv_stripesize);
2010 -       }
2011 +       if(lv->lv_stripes > 1) {
2012 +               sz += sprintf(page + sz, "stripes:      %u\n",
2013 +                             lv->lv_stripes);
2014 +               sz += sprintf(page + sz, "stripesize:   %u\n",
2015 +                             lv->lv_stripesize);
2016 +       }
2017         sz += sprintf(page + sz, "device:       %02u:%02u\n",
2018                       MAJOR(lv->lv_dev), MINOR(lv->lv_dev));
2019  
2020 @@ -626,4 +617,3 @@
2021         }
2022         *b = '\0';
2023  }
2024 -MODULE_LICENSE("GPL");
This page took 0.207158 seconds and 3 git commands to generate.