4 * Copyright (C) 1997 - 2000 Heinz Mauelshagen, Germany
6 * February-November 1997
7 * April-May,July-August,November 1998
8 * January-March,May,July,September,October 1999
9 * January,February 2000
12 * LVM driver is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or (at your option)
17 * LVM driver is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with GNU CC; see the file COPYING. If not, write to
24 * the Free Software Foundation, 59 Temple Place - Suite 330,
25 * Boston, MA 02111-1307, USA.
32 * 09/11/1997 - added chr ioctls VG_STATUS_GET_COUNT
33 * and VG_STATUS_GET_NAMELIST
34 * 18/01/1998 - change lvm_chr_open/close lock handling
35 * 30/04/1998 - changed LV_STATUS ioctl to LV_STATUS_BYNAME and
36 * - added LV_STATUS_BYINDEX ioctl
37 * - used lvm_status_byname_req_t and
38 * lvm_status_byindex_req_t vars
39 * 04/05/1998 - added multiple device support
40 * 08/05/1998 - added support to set/clear extendable flag in volume group
41 * 09/05/1998 - changed output of lvm_proc_get_info() because of
42 * support for free (eg. longer) logical volume names
43 * 12/05/1998 - added spin_locks (thanks to Pascal van Dam
44 * <pascal@ramoth.xs4all.nl>)
45 * 25/05/1998 - fixed handling of locked PEs in lvm_map() and lvm_chr_ioctl()
46 * 26/05/1998 - reactivated verify_area by access_ok
47 * 07/06/1998 - used vmalloc/vfree instead of kmalloc/kfree to go
48 * beyond 128/256 KB max allocation limit per call
49 * - #ifdef blocked spin_lock calls to avoid compile errors
51 * 11/06/1998 - another enhancement to spinlock code in lvm_chr_open()
52 * and use of LVM_VERSION_CODE instead of my own macros
53 * (thanks to Michael Marxmeier <mike@msede.com>)
54 * 07/07/1998 - added statistics in lvm_map()
55 * 08/07/1998 - saved statistics in lvm_do_lv_extend_reduce()
56 * 25/07/1998 - used __initfunc macro
57 * 02/08/1998 - changes for official char/block major numbers
58 * 07/08/1998 - avoided init_module() and cleanup_module() to be static
59 * 30/08/1998 - changed VG lv_open counter from sum of LV lv_open counters
60 * to sum of LVs open (no matter how often each is)
61 * 01/09/1998 - fixed lvm_gendisk.part[] index error
62 * 07/09/1998 - added copying of lv_current_pe-array
63 * in LV_STATUS_BYINDEX ioctl
64 * 17/11/1998 - added KERN_* levels to printk
65 * 13/01/1999 - fixed LV index bug in lvm_do_lv_create() which hit lvrename
66 * 07/02/1999 - fixed spinlock handling bug in case of LVM_RESET
67 * by moving spinlock code from lvm_chr_open()
69 * - added LVM_LOCK_LVM ioctl to lvm_chr_ioctl()
70 * - allowed LVM_RESET and retrieval commands to go ahead;
71 * only other update ioctls are blocked now
72 * - fixed pv->pe to NULL for pv_status
73 * - using lv_req structure in lvm_chr_ioctl() now
74 * - fixed NULL ptr reference bug in lvm_do_lv_extend_reduce()
75 * caused by uncontiguous PV array in lvm_chr_ioctl(VG_REDUCE)
76 * 09/02/1999 - changed BLKRASET and BLKRAGET in lvm_chr_ioctl() to
77 * handle lgoical volume private read ahead sector
78 * - implemented LV read_ahead handling with lvm_blk_read()
80 * 10/02/1999 - implemented 2.[12].* support function lvm_hd_name()
81 * to be used in drivers/block/genhd.c by disk_name()
82 * 12/02/1999 - fixed index bug in lvm_blk_ioctl(), HDIO_GETGEO
83 * - enhanced gendisk insert/remove handling
84 * 16/02/1999 - changed to dynamic block minor number allocation to
85 * have as much as 99 volume groups with 256 logical volumes
86 * as the grand total; this allows having 1 volume group with
87 * up to 256 logical volumes in it
88 * 21/02/1999 - added LV open count information to proc filesystem
89 * - substituted redundant LVM_RESET code by calls
90 * to lvm_do_vg_remove()
91 * 22/02/1999 - used schedule_timeout() to be more responsive
92 * in case of lvm_do_vg_remove() with lots of logical volumes
93 * 19/03/1999 - fixed NULL pointer bug in module_init/lvm_init
94 * 17/05/1999 - used DECLARE_WAIT_QUEUE_HEAD macro (>2.3.0)
95 * - enhanced lvm_hd_name support
96 * 03/07/1999 - avoided use of KERNEL_VERSION macro based ifdefs and
97 * memcpy_tofs/memcpy_fromfs macro redefinitions
98 * 06/07/1999 - corrected reads/writes statistic counter copy in case
99 * of striped logical volume
100 * 28/07/1999 - implemented snapshot logical volumes
102 * - LV_STATUS_BYINDEX
107 * - new lvm_snapshot_remap_block
108 * - new lvm_snapshot_remap_new_block
109 * 08/10/1999 - implemented support for multiple snapshots per
110 * original logical volume
111 * 12/10/1999 - support for 2.3.19
112 * 11/11/1999 - support for 2.3.28
113 * 21/11/1999 - changed lvm_map() interface to buffer_head based
114 * 19/12/1999 - support for 2.3.33
115 * 01/01/2000 - changed locking concept in lvm_map(),
116 * lvm_do_vg_create() and lvm_do_lv_remove()
117 * 15/01/2000 - fixed PV_FLUSH bug in lvm_chr_ioctl()
118 * 24/01/2000 - ported to 2.3.40 including Alan Cox's pointer changes etc.
119 * 29/01/2000 - used kmalloc/kfree again for all small structures
120 * 20/01/2000 - cleaned up lvm_chr_ioctl by moving code
121 * to seperated functions
122 * - avoided "/dev/" in proc filesystem output
123 * - avoided inline strings functions lvm_strlen etc.
124 * 14/02/2000 - support for 2.3.43
125 * - integrated Andrea Arcangeli's snapshot code
130 static char *lvm_version
= "LVM version 0.8final by Heinz Mauelshagen (15/02/2000)\n";
131 static char *lvm_short_version
= "version 0.8final (15/02/2000)";
133 #define MAJOR_NR LVM_BLK_MAJOR
134 #define DEVICE_OFF(device)
136 #include <linux/config.h>
137 #include <linux/version.h>
142 #include <linux/modversions.h>
145 #include <linux/module.h>
147 #include <linux/kernel.h>
148 #include <linux/vmalloc.h>
149 #include <linux/slab.h>
150 #include <linux/init.h>
152 #include <linux/hdreg.h>
153 #include <linux/stat.h>
154 #include <linux/fs.h>
155 #include <linux/proc_fs.h>
156 #include <linux/blkdev.h>
157 #include <linux/genhd.h>
158 #include <linux/locks.h>
159 #include <linux/smp_lock.h>
160 #include <asm/ioctl.h>
161 #include <asm/segment.h>
162 #include <asm/uaccess.h>
164 #ifdef CONFIG_KERNELD
165 #include <linux/kerneld.h>
168 #define LOCAL_END_REQUEST
170 #include <linux/blk.h>
171 #include <linux/blkpg.h>
173 #include <linux/errno.h>
174 #include <linux/lvm.h>
176 #define LVM_CORRECT_READ_AHEAD(a) \
177 (((a) < LVM_MIN_READ_AHEAD || (a) > LVM_MAX_READ_AHEAD) \
178 ? LVM_MAX_READ_AHEAD : (a))
181 # define WRITEA WRITE
185 * External function prototypes
188 int init_module(void);
189 void cleanup_module(void);
191 extern int lvm_init(void);
194 static void lvm_dummy_device_request(request_queue_t
*);
195 #define DEVICE_REQUEST lvm_dummy_device_request
197 static int lvm_make_request_fn(request_queue_t
*, int, struct buffer_head
*);
198 static void lvm_plug_device_noop(request_queue_t
*, kdev_t
);
200 static int lvm_blk_ioctl(struct inode
*, struct file
*, uint
, ulong
);
201 static int lvm_blk_open(struct inode
*, struct file
*);
203 static int lvm_chr_open(struct inode
*, struct file
*);
205 static int lvm_chr_close(struct inode
*, struct file
*);
206 static int lvm_blk_close(struct inode
*, struct file
*);
208 static int lvm_chr_ioctl(struct inode
*, struct file
*, uint
, ulong
);
210 #if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
211 static int lvm_proc_get_info(char *, char **, off_t
, int);
212 static int (*lvm_proc_get_info_ptr
) (char *, char **, off_t
, int) =
217 void lvm_hd_name(char *, int);
219 /* End external function prototypes */
223 * Internal function prototypes
225 static void lvm_init_vars(void);
227 /* external snapshot calls */
228 int lvm_snapshot_remap_block(kdev_t
*, ulong
*, ulong
, lv_t
*);
229 int lvm_snapshot_COW(kdev_t
, ulong
, ulong
, ulong
, lv_t
*);
230 int lvm_snapshot_alloc(lv_t
*);
231 void lvm_snapshot_release(lv_t
*);
234 extern void (*lvm_hd_name_ptr
) (char *, int);
236 static int lvm_map(struct buffer_head
*, int);
237 static int lvm_do_lock_lvm(void);
238 static int lvm_do_le_remap(vg_t
*, void *);
239 static int lvm_do_pe_lock_unlock(vg_t
*r
, void *);
240 static int lvm_do_vg_create(int, void *);
241 static int lvm_do_vg_extend(vg_t
*, void *);
242 static int lvm_do_vg_reduce(vg_t
*, void *);
243 static int lvm_do_vg_remove(int);
244 static int lvm_do_lv_create(int, char *, lv_t
*);
245 static int lvm_do_lv_remove(int, char *, int);
246 static int lvm_do_lv_extend_reduce(int, char *, lv_t
*);
247 static int lvm_do_lv_status_byname(vg_t
*r
, void *);
248 static int lvm_do_lv_status_byindex(vg_t
*, void *arg
);
249 static int lvm_do_pv_change(vg_t
*, void*);
250 static int lvm_do_pv_status(vg_t
*, void *);
251 static void lvm_geninit(struct gendisk
*);
253 static struct inode
*lvm_get_inode(int);
254 void lvm_clear_inode(struct inode
*);
256 /* END Internal function prototypes */
259 /* volume group descriptor area pointers */
260 static vg_t
*vg
[ABS_MAX_VG
];
261 static pv_t
*pvp
= NULL
;
262 static lv_t
*lvp
= NULL
;
263 static pe_t
*pep
= NULL
;
264 static pe_t
*pep1
= NULL
;
267 /* map from block minor number to VG and LV numbers */
272 static vg_lv_map_t vg_lv_map
[ABS_MAX_LV
];
275 /* Request structures (lvm_chr_ioctl()) */
276 static pv_change_req_t pv_change_req
;
277 static pv_flush_req_t pv_flush_req
;
278 static pv_status_req_t pv_status_req
;
279 static pe_lock_req_t pe_lock_req
;
280 static le_remap_req_t le_remap_req
;
281 static lv_req_t lv_req
;
283 #ifdef LVM_TOTAL_RESET
284 static int lvm_reset_spindown
= 0;
287 static char pv_name
[NAME_LEN
];
288 /* static char rootvg[NAME_LEN] = { 0, }; */
289 static uint lv_open
= 0;
290 const char *const lvm_name
= LVM_NAME
;
292 static int loadtime
= 0;
293 static uint vg_count
= 0;
294 static long lvm_chr_open_count
= 0;
295 static ushort lvm_iop_version
= LVM_DRIVER_IOP_VERSION
;
296 static DECLARE_WAIT_QUEUE_HEAD(lvm_snapshot_wait
);
297 static DECLARE_WAIT_QUEUE_HEAD(lvm_wait
);
298 static DECLARE_WAIT_QUEUE_HEAD(lvm_map_wait
);
300 static spinlock_t lvm_lock
= SPIN_LOCK_UNLOCKED
;
302 static devfs_handle_t lvm_devfs_handle
;
303 static devfs_handle_t vg_devfs_handle
[MAX_VG
];
304 static devfs_handle_t ch_devfs_handle
[MAX_VG
];
305 static devfs_handle_t lv_devfs_handle
[MAX_LV
];
307 static struct file_operations lvm_chr_fops
=
311 release
: lvm_chr_close
,
312 ioctl
: lvm_chr_ioctl
,
315 static struct block_device_operations lvm_blk_dops
=
318 release
: lvm_blk_close
,
322 /* gendisk structures */
323 static struct hd_struct lvm_hd_struct
[MAX_LV
];
324 static int lvm_blocksizes
[MAX_LV
] =
326 static int lvm_size
[MAX_LV
] =
328 static struct gendisk lvm_gendisk
=
330 MAJOR_NR
, /* major # */
331 LVM_NAME
, /* name of major */
332 0, /* number of times minor is shifted
334 1, /* maximum partitions per device */
335 lvm_hd_struct
, /* partition table */
336 lvm_size
, /* device size in blocks, copied
338 MAX_LV
, /* number or real devices */
340 NULL
, /* pointer to next gendisk struct (internal) */
346 * Module initialization...
348 int init_module(void)
351 * Driver initialization...
354 __initfunc(int lvm_init(void))
356 int __init
lvm_init(void)
358 #endif /* #ifdef MODULE */
360 struct gendisk
*gendisk_ptr
= NULL
;
362 if (register_chrdev(LVM_CHAR_MAJOR
, lvm_name
, &lvm_chr_fops
) < 0) {
363 printk(KERN_ERR
"%s -- register_chrdev failed\n", lvm_name
);
366 if (register_blkdev(MAJOR_NR
, lvm_name
, &lvm_blk_dops
) < 0) {
367 printk("%s -- register_blkdev failed\n", lvm_name
);
368 if (unregister_chrdev(LVM_CHAR_MAJOR
, lvm_name
) < 0)
369 printk(KERN_ERR
"%s -- unregister_chrdev failed\n", lvm_name
);
373 lvm_devfs_handle
= devfs_register(
374 0 , "lvm", 0, 0, LVM_CHAR_MAJOR
,
375 S_IFCHR
| S_IRUSR
| S_IWUSR
| S_IRGRP
,
376 &lvm_chr_fops
, NULL
);
378 #if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
379 create_proc_info_entry(LVM_NAME
, S_IFREG
| S_IRUGO
,
380 &proc_root
, lvm_proc_get_info_ptr
);
384 lvm_geninit(&lvm_gendisk
);
386 /* insert our gendisk at the corresponding major */
387 if (gendisk_head
!= NULL
) {
388 gendisk_ptr
= gendisk_head
;
389 while (gendisk_ptr
->next
!= NULL
&&
390 gendisk_ptr
->major
> lvm_gendisk
.major
) {
391 gendisk_ptr
= gendisk_ptr
->next
;
393 lvm_gendisk
.next
= gendisk_ptr
->next
;
394 gendisk_ptr
->next
= &lvm_gendisk
;
396 gendisk_head
= &lvm_gendisk
;
397 lvm_gendisk
.next
= NULL
;
401 /* reference from drivers/block/genhd.c */
402 lvm_hd_name_ptr
= lvm_hd_name
;
405 blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR
), DEVICE_REQUEST
);
406 blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR
), lvm_make_request_fn
);
407 blk_queue_pluggable(BLK_DEFAULT_QUEUE(MAJOR_NR
), lvm_plug_device_noop
);
408 /* optional read root VGDA */
410 if ( *rootvg != 0) vg_read_with_pv_and_lv ( rootvg, &vg);
420 " successfully initialized\n",
421 lvm_version
, lvm_name
);
424 } /* init_module() / lvm_init() */
431 void cleanup_module(void)
433 struct gendisk
*gendisk_ptr
= NULL
, *gendisk_ptr_prev
= NULL
;
435 devfs_unregister (lvm_devfs_handle
);
437 if (unregister_chrdev(LVM_CHAR_MAJOR
, lvm_name
) < 0) {
438 printk(KERN_ERR
"%s -- unregister_chrdev failed\n", lvm_name
);
440 if (unregister_blkdev(MAJOR_NR
, lvm_name
) < 0) {
441 printk(KERN_ERR
"%s -- unregister_blkdev failed\n", lvm_name
);
443 blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR
));
445 gendisk_ptr
= gendisk_ptr_prev
= gendisk_head
;
446 while (gendisk_ptr
!= NULL
) {
447 if (gendisk_ptr
== &lvm_gendisk
)
449 gendisk_ptr_prev
= gendisk_ptr
;
450 gendisk_ptr
= gendisk_ptr
->next
;
452 /* delete our gendisk from chain */
453 if (gendisk_ptr
== &lvm_gendisk
)
454 gendisk_ptr_prev
->next
= gendisk_ptr
->next
;
456 blk_size
[MAJOR_NR
] = NULL
;
457 blksize_size
[MAJOR_NR
] = NULL
;
459 #if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
460 remove_proc_entry(LVM_NAME
, &proc_root
);
464 /* reference from linux/drivers/block/genhd.c */
465 lvm_hd_name_ptr
= NULL
;
468 printk(KERN_INFO
"%s -- Module successfully deactivated\n", lvm_name
);
471 } /* void cleanup_module() */
472 #endif /* #ifdef MODULE */
476 * support function to initialize lvm variables
479 __initfunc(void lvm_init_vars(void))
481 void __init
lvm_init_vars(void)
486 loadtime
= CURRENT_TIME
;
488 pe_lock_req
.lock
= UNLOCK_PE
;
489 pe_lock_req
.data
.lv_dev
= \
490 pe_lock_req
.data
.pv_dev
= \
491 pe_lock_req
.data
.pv_offset
= 0;
493 /* Initialize VG pointers */
494 for (v
= 0; v
< ABS_MAX_VG
; v
++) vg
[v
] = NULL
;
496 /* Initialize LV -> VG association */
497 for (v
= 0; v
< ABS_MAX_LV
; v
++) {
498 /* index ABS_MAX_VG never used for real VG */
499 vg_lv_map
[v
].vg_number
= ABS_MAX_VG
;
500 vg_lv_map
[v
].lv_number
= -1;
504 } /* lvm_init_vars() */
507 /********************************************************************
509 * Character device functions
511 ********************************************************************/
514 * character device open routine
516 static int lvm_chr_open(struct inode
*inode
,
519 int minor
= MINOR(inode
->i_rdev
);
523 "%s -- lvm_chr_open MINOR: %d VG#: %d mode: 0x%X lock: %d\n",
524 lvm_name
, minor
, VG_CHR(minor
), file
->f_mode
, lock
);
527 /* super user validation */
528 if (!capable(CAP_SYS_ADMIN
)) return -EACCES
;
530 /* Group special file open */
531 if (VG_CHR(minor
) > MAX_VG
) return -ENXIO
;
533 lvm_chr_open_count
++;
535 } /* lvm_chr_open() */
539 * character device i/o-control routine
541 * Only one changing process can do changing ioctl at one time,
545 static int lvm_chr_ioctl(struct inode
*inode
, struct file
*file
,
546 uint command
, ulong a
)
548 int minor
= MINOR(inode
->i_rdev
);
549 uint extendable
, l
, v
;
550 void *arg
= (void *) a
;
552 vg_t
* vg_ptr
= vg
[VG_CHR(minor
)];
554 /* otherwise cc will complain about unused variables */
560 "%s -- lvm_chr_ioctl: command: 0x%X MINOR: %d "
561 "VG#: %d mode: 0x%X\n",
562 lvm_name
, command
, minor
, VG_CHR(minor
), file
->f_mode
);
565 #ifdef LVM_TOTAL_RESET
566 if (lvm_reset_spindown
> 0) return -EACCES
;
569 /* Main command switch */
573 return lvm_do_lock_lvm();
575 case LVM_GET_IOP_VERSION
:
576 /* check lvm version to ensure driver/tools+lib
578 if (copy_to_user(arg
, &lvm_iop_version
, sizeof(ushort
)) != 0)
582 #ifdef LVM_TOTAL_RESET
584 /* lock reset function */
585 lvm_reset_spindown
= 1;
586 for (v
= 0; v
< ABS_MAX_VG
; v
++) {
587 if (vg
[v
] != NULL
) lvm_do_vg_remove(v
);
591 while (GET_USE_COUNT(&__this_module
) < 1)
593 while (GET_USE_COUNT(&__this_module
) > 1)
596 lock
= 0; /* release lock */
597 wake_up_interruptible(&lvm_wait
);
599 #endif /* LVM_TOTAL_RESET */
603 /* remap a logical extent (after moving the physical extent) */
604 return lvm_do_le_remap(vg_ptr
,arg
);
607 /* lock/unlock i/o to a physical extent to move it to another
608 physical volume (move's done in user space's pvmove) */
609 return lvm_do_pe_lock_unlock(vg_ptr
,arg
);
613 return lvm_do_vg_create(minor
, arg
);
616 /* remove an inactive VGDA */
617 return lvm_do_vg_remove(minor
);
620 /* extend a volume group */
621 return lvm_do_vg_extend(vg_ptr
,arg
);
624 /* reduce a volume group */
625 return lvm_do_vg_reduce(vg_ptr
,arg
);
628 case VG_SET_EXTENDABLE
:
629 /* set/clear extendability flag of volume group */
630 if (vg_ptr
== NULL
) return -ENXIO
;
631 if (copy_from_user(&extendable
, arg
, sizeof(extendable
)) != 0)
634 if (extendable
== VG_EXTENDABLE
||
635 extendable
== ~VG_EXTENDABLE
) {
636 if (extendable
== VG_EXTENDABLE
)
637 vg_ptr
->vg_status
|= VG_EXTENDABLE
;
639 vg_ptr
->vg_status
&= ~VG_EXTENDABLE
;
640 } else return -EINVAL
;
645 /* get volume group data (only the vg_t struct) */
646 if (vg_ptr
== NULL
) return -ENXIO
;
647 if (copy_to_user(arg
, vg_ptr
, sizeof(vg_t
)) != 0)
652 case VG_STATUS_GET_COUNT
:
653 /* get volume group count */
654 if (copy_to_user(arg
, &vg_count
, sizeof(vg_count
)) != 0)
659 case VG_STATUS_GET_NAMELIST
:
660 /* get volume group count */
661 for (l
= v
= 0; v
< ABS_MAX_VG
; v
++) {
663 if (copy_to_user(arg
+ l
++ * NAME_LEN
,
676 /* create, remove, extend or reduce a logical volume */
677 if (vg_ptr
== NULL
) return -ENXIO
;
678 if (copy_from_user(&lv_req
, arg
, sizeof(lv_req
)) != 0)
681 if (command
!= LV_REMOVE
) {
682 if (copy_from_user(&lv
, lv_req
.lv
, sizeof(lv_t
)) != 0)
687 return lvm_do_lv_create(minor
, lv_req
.lv_name
, &lv
);
690 return lvm_do_lv_remove(minor
, lv_req
.lv_name
, -1);
694 return lvm_do_lv_extend_reduce(minor
, lv_req
.lv_name
, &lv
);
698 case LV_STATUS_BYNAME
:
699 /* get status of a logical volume by name */
700 return lvm_do_lv_status_byname(vg_ptr
,arg
);
702 case LV_STATUS_BYINDEX
:
703 /* get status of a logical volume by index */
704 return lvm_do_lv_status_byindex(vg_ptr
,arg
);
707 /* change a physical volume */
708 return lvm_do_pv_change(vg_ptr
,arg
);
711 /* get physical volume data (pv_t structure only) */
712 return lvm_do_pv_status(vg_ptr
,arg
);
715 /* physical volume buffer flush/invalidate */
716 if (copy_from_user(&pv_flush_req
, arg
,
717 sizeof(pv_flush_req
)) != 0)
720 for ( v
= 0; v
< ABS_MAX_VG
; v
++) {
722 if ( vg
[v
] == NULL
) continue;
723 for ( p
= 0; p
< vg
[v
]->pv_max
; p
++) {
724 if ( vg
[v
]->pv
[p
] != NULL
&&
725 strcmp ( vg
[v
]->pv
[p
]->pv_name
,
726 pv_flush_req
.pv_name
) == 0) {
727 fsync_dev ( vg
[v
]->pv
[p
]->pv_dev
);
728 invalidate_buffers ( vg
[v
]->pv
[p
]->pv_dev
);
737 "%s -- lvm_chr_ioctl: unknown command %x\n",
743 } /* lvm_chr_ioctl */
747 * character device close routine
749 static int lvm_chr_close(struct inode
*inode
, struct file
*file
)
752 int minor
= MINOR(inode
->i_rdev
);
754 "%s -- lvm_chr_close VG#: %d\n", lvm_name
, VG_CHR(minor
));
758 #ifdef LVM_TOTAL_RESET
759 if (lvm_reset_spindown
> 0) {
760 lvm_reset_spindown
= 0;
761 lvm_chr_open_count
= 1;
765 if (lvm_chr_open_count
> 0) lvm_chr_open_count
--;
766 if (lock
== current
->pid
) {
767 lock
= 0; /* release lock */
768 wake_up_interruptible(&lvm_wait
);
773 } /* lvm_chr_close() */
777 /********************************************************************
779 * Block device functions
781 ********************************************************************/
784 * block device open routine
786 static int lvm_blk_open(struct inode
*inode
, struct file
*file
)
788 int minor
= MINOR(inode
->i_rdev
);
790 vg_t
*vg_ptr
= vg
[VG_BLK(minor
)];
792 #ifdef DEBUG_LVM_BLK_OPEN
794 "%s -- lvm_blk_open MINOR: %d VG#: %d LV#: %d mode: 0x%X\n",
795 lvm_name
, minor
, VG_BLK(minor
), LV_BLK(minor
), file
->f_mode
);
798 #ifdef LVM_TOTAL_RESET
799 if (lvm_reset_spindown
> 0)
803 if (vg_ptr
!= NULL
&&
804 (vg_ptr
->vg_status
& VG_ACTIVE
) &&
805 (lv_ptr
= vg_ptr
->lv
[LV_BLK(minor
)]) != NULL
&&
806 LV_BLK(minor
) >= 0 &&
807 LV_BLK(minor
) < vg_ptr
->lv_max
) {
809 /* Check parallel LV spindown (LV remove) */
810 if (lv_ptr
->lv_status
& LV_SPINDOWN
) return -EPERM
;
812 /* Check inactive LV and open for read/write */
813 if (file
->f_mode
& O_RDWR
) {
814 if (!(lv_ptr
->lv_status
& LV_ACTIVE
)) return -EPERM
;
815 if (!(lv_ptr
->lv_access
& LV_WRITE
)) return -EACCES
;
818 /* be sure to increment VG counter */
819 if (lv_ptr
->lv_open
== 0) vg_ptr
->lv_open
++;
824 #ifdef DEBUG_LVM_BLK_OPEN
826 "%s -- lvm_blk_open MINOR: %d VG#: %d LV#: %d size: %d\n",
827 lvm_name
, minor
, VG_BLK(minor
), LV_BLK(minor
),
834 } /* lvm_blk_open() */
838 * block device i/o-control routine
840 static int lvm_blk_ioctl(struct inode
*inode
, struct file
*file
,
841 uint command
, ulong a
)
843 int minor
= MINOR(inode
->i_rdev
);
844 vg_t
*vg_ptr
= vg
[VG_BLK(minor
)];
845 lv_t
*lv_ptr
= vg_ptr
->lv
[LV_BLK(minor
)];
846 void *arg
= (void *) a
;
847 struct hd_geometry
*hd
= (struct hd_geometry
*) a
;
851 "%s -- lvm_blk_ioctl MINOR: %d command: 0x%X arg: %X "
852 "VG#: %dl LV#: %d\n",
853 lvm_name
, minor
, command
, (ulong
) arg
,
854 VG_BLK(minor
), LV_BLK(minor
));
859 /* return device size */
862 "%s -- lvm_blk_ioctl -- BLKGETSIZE: %u\n",
863 lvm_name
, lv_ptr
->lv_size
);
865 if (put_user(lv_ptr
->lv_size
, (long *)arg
))
871 /* flush buffer cache */
872 if (!capable(CAP_SYS_ADMIN
)) return -EACCES
;
876 "%s -- lvm_blk_ioctl -- BLKFLSBUF\n", lvm_name
);
878 fsync_dev(inode
->i_rdev
);
879 invalidate_buffers(inode
->i_rdev
);
884 /* set read ahead for block device */
885 if (!capable(CAP_SYS_ADMIN
)) return -EACCES
;
889 "%s -- lvm_blk_ioctl -- BLKRASET: %d sectors for %02X:%02X\n",
890 lvm_name
, (long) arg
, MAJOR(inode
->i_rdev
), minor
);
892 if ((long) arg
< LVM_MIN_READ_AHEAD
||
893 (long) arg
> LVM_MAX_READ_AHEAD
)
895 read_ahead
[MAJOR_NR
] = lv_ptr
->lv_read_ahead
= (long) arg
;
900 /* get current read ahead setting */
903 "%s -- lvm_blk_ioctl -- BLKRAGET\n", lvm_name
);
905 if (put_user(lv_ptr
->lv_read_ahead
, (long *)arg
))
911 /* get disk geometry */
914 "%s -- lvm_blk_ioctl -- HDIO_GETGEO\n", lvm_name
);
919 unsigned char heads
= 64;
920 unsigned char sectors
= 32;
922 short cylinders
= lv_ptr
->lv_size
/ heads
/ sectors
;
924 if (copy_to_user((char *) &hd
->heads
, &heads
,
925 sizeof(heads
)) != 0 ||
926 copy_to_user((char *) &hd
->sectors
, §ors
,
927 sizeof(sectors
)) != 0 ||
928 copy_to_user((short *) &hd
->cylinders
,
929 &cylinders
, sizeof(cylinders
)) != 0 ||
930 copy_to_user((long *) &hd
->start
, &start
,
937 "%s -- lvm_blk_ioctl -- cylinders: %d\n",
938 lvm_name
, lv_ptr
->lv_size
/ heads
/ sectors
);
944 /* set access flags of a logical volume */
945 if (!capable(CAP_SYS_ADMIN
)) return -EACCES
;
946 lv_ptr
->lv_access
= (ulong
) arg
;
951 /* set status flags of a logical volume */
952 if (!capable(CAP_SYS_ADMIN
)) return -EACCES
;
953 if (!((ulong
) arg
& LV_ACTIVE
) && lv_ptr
->lv_open
> 1)
955 lv_ptr
->lv_status
= (ulong
) arg
;
959 case LV_SET_ALLOCATION
:
960 /* set allocation flags of a logical volume */
961 if (!capable(CAP_SYS_ADMIN
)) return -EACCES
;
962 lv_ptr
->lv_allocation
= (ulong
) arg
;
968 "%s -- lvm_blk_ioctl: unknown command %d\n",
974 } /* lvm_blk_ioctl() */
978 * block device close routine
980 static int lvm_blk_close(struct inode
*inode
, struct file
*file
)
982 int minor
= MINOR(inode
->i_rdev
);
983 vg_t
*vg_ptr
= vg
[VG_BLK(minor
)];
984 lv_t
*lv_ptr
= vg_ptr
->lv
[LV_BLK(minor
)];
988 "%s -- lvm_blk_close MINOR: %d VG#: %d LV#: %d\n",
989 lvm_name
, minor
, VG_BLK(minor
), LV_BLK(minor
));
992 sync_dev(inode
->i_rdev
);
993 if (lv_ptr
->lv_open
== 1) vg_ptr
->lv_open
--;
999 } /* lvm_blk_close() */
1002 #if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
1004 * Support function /proc-Filesystem
1006 #define LVM_PROC_BUF ( i == 0 ? dummy_buf : &buf[sz])
1008 static int lvm_proc_get_info(char *page
, char **start
, off_t pos
, int count
)
1010 int c
, i
, l
, p
, v
, vg_counter
, pv_counter
, lv_counter
, lv_open_counter
,
1011 lv_open_total
, pe_t_bytes
, lv_block_exception_t_bytes
, seconds
;
1014 char allocation_flag
, inactive_flag
, rw_flag
, stripes_flag
;
1015 char *lv_name
, *pv_name
;
1016 static char *buf
= NULL
;
1017 static char dummy_buf
[160]; /* sized for 2 lines */
1023 #ifdef DEBUG_LVM_PROC_GET_INFO
1025 "%s - lvm_proc_get_info CALLED pos: %lu count: %d whence: %d\n",
1026 lvm_name
, pos
, count
, whence
);
1029 if (pos
== 0 || buf
== NULL
) {
1030 sz_last
= vg_counter
= pv_counter
= lv_counter
= lv_open_counter
= \
1031 lv_open_total
= pe_t_bytes
= lv_block_exception_t_bytes
= 0;
1033 /* search for activity */
1034 for (v
= 0; v
< ABS_MAX_VG
; v
++) {
1035 if ((vg_ptr
= vg
[v
]) != NULL
) {
1037 pv_counter
+= vg_ptr
->pv_cur
;
1038 lv_counter
+= vg_ptr
->lv_cur
;
1039 if (vg_ptr
->lv_cur
> 0) {
1040 for (l
= 0; l
< vg
[v
]->lv_max
; l
++) {
1041 if ((lv_ptr
= vg_ptr
->lv
[l
]) != NULL
) {
1042 pe_t_bytes
+= lv_ptr
->lv_allocated_le
;
1043 if (lv_ptr
->lv_block_exception
!= NULL
)
1044 lv_block_exception_t_bytes
+= lv_ptr
->lv_remap_end
;
1045 if (lv_ptr
->lv_open
> 0) {
1047 lv_open_total
+= lv_ptr
->lv_open
;
1054 pe_t_bytes
*= sizeof(pe_t
);
1055 lv_block_exception_t_bytes
*= sizeof(lv_block_exception_t
);
1060 "%s -- kfree %d\n", lvm_name
, __LINE__
);
1065 /* 2 times: first to get size to allocate buffer,
1066 2nd to fill the malloced buffer */
1067 for (i
= 0; i
< 2; i
++) {
1069 sz
+= sprintf(LVM_PROC_BUF
,
1077 "Total: %d VG%s %d PV%s %d LV%s ",
1079 vg_counter
, vg_counter
== 1 ? "" : "s",
1080 pv_counter
, pv_counter
== 1 ? "" : "s",
1081 lv_counter
, lv_counter
== 1 ? "" : "s");
1082 sz
+= sprintf(LVM_PROC_BUF
,
1085 lv_open_counter
== 1 ? "" : "s");
1086 if (lv_open_total
> 0)
1087 sz
+= sprintf(LVM_PROC_BUF
,
1091 sz
+= sprintf(LVM_PROC_BUF
, ")");
1092 sz
+= sprintf(LVM_PROC_BUF
,
1093 "\nGlobal: %lu bytes malloced IOP version: %d ",
1094 vg_counter
* sizeof(vg_t
) +
1095 pv_counter
* sizeof(pv_t
) +
1096 lv_counter
* sizeof(lv_t
) +
1097 pe_t_bytes
+ lv_block_exception_t_bytes
+ sz_last
,
1100 seconds
= CURRENT_TIME
- loadtime
;
1102 loadtime
= CURRENT_TIME
+ seconds
;
1103 if (seconds
/ 86400 > 0) {
1104 sz
+= sprintf(LVM_PROC_BUF
, "%d day%s ",
1106 seconds
/ 86400 == 0 ||
1107 seconds
/ 86400 > 1 ? "s" : "");
1109 sz
+= sprintf(LVM_PROC_BUF
, "%d:%02d:%02d active\n",
1110 (seconds
% 86400) / 3600,
1111 (seconds
% 3600) / 60,
1114 if (vg_counter
> 0) {
1115 for (v
= 0; v
< ABS_MAX_VG
; v
++) {
1117 if ((vg_ptr
= vg
[v
]) != NULL
) {
1118 inactive_flag
= ' ';
1119 if (!(vg_ptr
->vg_status
& VG_ACTIVE
)) inactive_flag
= 'I';
1120 sz
+= sprintf(LVM_PROC_BUF
,
1121 "\nVG: %c%s [%d PV, %d LV/%d open] "
1123 " Usage [KB/PE]: %d /%d total "
1124 "%d /%d used %d /%d free",
1130 vg_ptr
->pe_size
>> 1,
1131 vg_ptr
->pe_size
* vg_ptr
->pe_total
>> 1,
1133 vg_ptr
->pe_allocated
* vg_ptr
->pe_size
>> 1,
1134 vg_ptr
->pe_allocated
,
1135 (vg_ptr
->pe_total
- vg_ptr
->pe_allocated
) *
1136 vg_ptr
->pe_size
>> 1,
1137 vg_ptr
->pe_total
- vg_ptr
->pe_allocated
);
1139 /* physical volumes */
1140 sz
+= sprintf(LVM_PROC_BUF
,
1142 vg_ptr
->pv_cur
== 1 ? ": " : "s:");
1144 for (p
= 0; p
< vg_ptr
->pv_max
; p
++) {
1145 if ((pv_ptr
= vg_ptr
->pv
[p
]) != NULL
) {
1146 inactive_flag
= 'A';
1147 if (!(pv_ptr
->pv_status
& PV_ACTIVE
))
1148 inactive_flag
= 'I';
1149 allocation_flag
= 'A';
1150 if (!(pv_ptr
->pv_allocatable
& PV_ALLOCATABLE
))
1151 allocation_flag
= 'N';
1152 pv_name
= strchr(pv_ptr
->pv_name
+1,'/');
1153 if ( pv_name
== 0) pv_name
= pv_ptr
->pv_name
;
1155 sz
+= sprintf(LVM_PROC_BUF
,
1156 "[%c%c] %-21s %8d /%-6d "
1157 "%8d /%-6d %8d /%-6d",
1162 pv_ptr
->pe_size
>> 1,
1164 pv_ptr
->pe_allocated
*
1165 pv_ptr
->pe_size
>> 1,
1166 pv_ptr
->pe_allocated
,
1168 pv_ptr
->pe_allocated
) *
1169 pv_ptr
->pe_size
>> 1,
1171 pv_ptr
->pe_allocated
);
1173 if (c
< vg_ptr
->pv_cur
)
1174 sz
+= sprintf(LVM_PROC_BUF
,
1179 /* logical volumes */
1180 sz
+= sprintf(LVM_PROC_BUF
,
1182 vg_ptr
->lv_cur
== 1 ? ": " : "s:");
1184 for (l
= 0; l
< vg
[v
]->lv_max
; l
++) {
1185 if ((lv_ptr
= vg_ptr
->lv
[l
]) != NULL
) {
1186 inactive_flag
= 'A';
1187 if (!(lv_ptr
->lv_status
& LV_ACTIVE
))
1188 inactive_flag
= 'I';
1190 if (lv_ptr
->lv_access
& LV_WRITE
)
1192 allocation_flag
= 'D';
1193 if (lv_ptr
->lv_allocation
& LV_CONTIGUOUS
)
1194 allocation_flag
= 'C';
1196 if (lv_ptr
->lv_stripes
> 1)
1198 sz
+= sprintf(LVM_PROC_BUF
,
1204 if (lv_ptr
->lv_stripes
> 1)
1205 sz
+= sprintf(LVM_PROC_BUF
, "%-2d",
1206 lv_ptr
->lv_stripes
);
1208 sz
+= sprintf(LVM_PROC_BUF
, " ");
1209 lv_name
= strrchr(lv_ptr
->lv_name
, '/');
1210 if ( lv_name
== 0) lv_name
= lv_ptr
->lv_name
;
1212 sz
+= sprintf(LVM_PROC_BUF
, "] %-25s", lv_name
);
1213 if (strlen(lv_name
) > 25)
1214 sz
+= sprintf(LVM_PROC_BUF
,
1216 sz
+= sprintf(LVM_PROC_BUF
, "%9d /%-6d ",
1217 lv_ptr
->lv_size
>> 1,
1218 lv_ptr
->lv_size
/ vg
[v
]->pe_size
);
1220 if (lv_ptr
->lv_open
== 0)
1221 sz
+= sprintf(LVM_PROC_BUF
, "close");
1223 sz
+= sprintf(LVM_PROC_BUF
, "%dx open",
1226 if (c
< vg_ptr
->lv_cur
)
1227 sz
+= sprintf(LVM_PROC_BUF
,
1231 if (vg_ptr
->lv_cur
== 0) sz
+= sprintf(LVM_PROC_BUF
, "none");
1232 sz
+= sprintf(LVM_PROC_BUF
, "\n");
1237 if ((buf
= vmalloc(sz
)) == NULL
) {
1239 return sprintf(page
, "%s - vmalloc error at line %d\n",
1240 lvm_name
, __LINE__
);
1252 if (sz
- pos
< count
)
1256 } /* lvm_proc_get_info() */
1257 #endif /* #if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS */
1261 * block device support function for /usr/src/linux/drivers/block/ll_rw_blk.c
1262 * (see init_module/lvm_init)
1264 static int lvm_map(struct buffer_head
*bh
, int rw
)
1266 int minor
= MINOR(bh
->b_rdev
);
1269 ulong size
= bh
->b_size
>> 9;
1270 ulong rsector_tmp
= bh
->b_rsector
;
1272 kdev_t rdev_tmp
= bh
->b_rdev
;
1274 lv_t
*lv
= vg
[VG_BLK(minor
)]->lv
[LV_BLK(minor
)];
1277 if (!(lv
->lv_status
& LV_ACTIVE
)) {
1279 "%s - lvm_map: ll_rw_blk for inactive LV %s\n",
1280 lvm_name
, lv
->lv_name
);
1284 if ( lv->lv_access & LV_SNAPSHOT)
1285 printk ( "%s -- %02d:%02d block: %lu rw: %d\n", lvm_name, MAJOR ( bh->b_dev), MINOR ( bh->b_dev), bh->b_blocknr, rw);
1288 /* take care of snapshot chunk writes before
1289 check for writable logical volume */
1290 if ((lv
->lv_access
& LV_SNAPSHOT
) &&
1291 MAJOR(bh
->b_rdev
) != 0 &&
1292 MAJOR(bh
->b_rdev
) != MAJOR_NR
&&
1293 (rw
== WRITEA
|| rw
== WRITE
))
1295 printk ( "%s -- doing snapshot write for %02d:%02d[%02d:%02d] b_blocknr: %lu b_rsector: %lu\n", lvm_name
, MAJOR ( bh
->b_dev
), MINOR ( bh
->b_dev
), MAJOR ( bh
->b_rdev
), MINOR ( bh
->b_rdev
), bh
->b_blocknr
, bh
->b_rsector
);
1299 if ((rw
== WRITE
|| rw
== WRITEA
) &&
1300 !(lv
->lv_access
& LV_WRITE
)) {
1302 "%s - lvm_map: ll_rw_blk write for readonly LV %s\n",
1303 lvm_name
, lv
->lv_name
);
1308 "%s - lvm_map minor:%d *rdev: %02d:%02d *rsector: %lu "
1316 if (rsector_tmp
+ size
> lv
->lv_size
) {
1318 "%s - lvm_map *rsector: %lu or size: %lu wrong for"
1319 " minor: %2d\n", lvm_name
, rsector_tmp
, size
, minor
);
1322 rsector_sav
= rsector_tmp
;
1323 rdev_sav
= rdev_tmp
;
1326 /* linear mapping */
1327 if (lv
->lv_stripes
< 2) {
1329 index
= rsector_tmp
/ vg
[VG_BLK(minor
)]->pe_size
;
1330 pe_start
= lv
->lv_current_pe
[index
].pe
;
1331 rsector_tmp
= lv
->lv_current_pe
[index
].pe
+
1332 (rsector_tmp
% vg
[VG_BLK(minor
)]->pe_size
);
1333 rdev_tmp
= lv
->lv_current_pe
[index
].dev
;
1337 "lv_current_pe[%ld].pe: %ld rdev: %02d:%02d rsector:%ld\n",
1339 lv
->lv_current_pe
[index
].pe
,
1345 /* striped mapping */
1348 ulong stripe_length
;
1350 stripe_length
= vg
[VG_BLK(minor
)]->pe_size
* lv
->lv_stripes
;
1351 stripe_index
= (rsector_tmp
% stripe_length
) / lv
->lv_stripesize
;
1352 index
= rsector_tmp
/ stripe_length
+
1353 (stripe_index
% lv
->lv_stripes
) *
1354 (lv
->lv_allocated_le
/ lv
->lv_stripes
);
1355 pe_start
= lv
->lv_current_pe
[index
].pe
;
1356 rsector_tmp
= lv
->lv_current_pe
[index
].pe
+
1357 (rsector_tmp
% stripe_length
) -
1358 (stripe_index
% lv
->lv_stripes
) * lv
->lv_stripesize
-
1359 stripe_index
/ lv
->lv_stripes
*
1360 (lv
->lv_stripes
- 1) * lv
->lv_stripesize
;
1361 rdev_tmp
= lv
->lv_current_pe
[index
].dev
;
1366 "lv_current_pe[%ld].pe: %ld rdev: %02d:%02d rsector:%ld\n"
1367 "stripe_length: %ld stripe_index: %ld\n",
1369 lv
->lv_current_pe
[index
].pe
,
1377 /* handle physical extents on the move */
1378 if (pe_lock_req
.lock
== LOCK_PE
) {
1379 if (rdev_tmp
== pe_lock_req
.data
.pv_dev
&&
1380 rsector_tmp
>= pe_lock_req
.data
.pv_offset
&&
1381 rsector_tmp
< (pe_lock_req
.data
.pv_offset
+
1382 vg
[VG_BLK(minor
)]->pe_size
)) {
1383 sleep_on(&lvm_map_wait
);
1384 rsector_tmp
= rsector_sav
;
1385 rdev_tmp
= rdev_sav
;
1386 goto lvm_second_remap
;
1390 if (rw
== WRITE
|| rw
== WRITEA
)
1391 lv
->lv_current_pe
[index
].writes
++;
1393 lv
->lv_current_pe
[index
].reads
++;
1395 /* snapshot volume exception handling on physical device address base */
1396 if (lv
->lv_access
& (LV_SNAPSHOT
| LV_SNAPSHOT_ORG
)) {
1397 /* original logical volume */
1398 if (lv
->lv_access
& LV_SNAPSHOT_ORG
) {
1399 if (rw
== WRITE
|| rw
== WRITEA
)
1403 /* start with first snapshot and loop thrugh all of them */
1404 for (lv_ptr
= lv
->lv_snapshot_next
;
1406 lv_ptr
= lv_ptr
->lv_snapshot_next
) {
1407 down(&lv
->lv_snapshot_org
->lv_snapshot_sem
);
1408 /* do we still have exception storage for this snapshot free? */
1409 if (lv_ptr
->lv_block_exception
!= NULL
) {
1410 rdev_sav
= rdev_tmp
;
1411 rsector_sav
= rsector_tmp
;
1412 if (!lvm_snapshot_remap_block(&rdev_tmp
,
1416 /* create a new mapping */
1417 lvm_snapshot_COW(rdev_tmp
,
1423 rdev_tmp
= rdev_sav
;
1424 rsector_tmp
= rsector_sav
;
1426 up(&lv
->lv_snapshot_org
->lv_snapshot_sem
);
1430 /* remap snapshot logical volume */
1431 down(&lv
->lv_snapshot_sem
);
1432 if (lv
->lv_block_exception
!= NULL
)
1433 lvm_snapshot_remap_block(&rdev_tmp
, &rsector_tmp
, pe_start
, lv
);
1434 up(&lv
->lv_snapshot_sem
);
1437 bh
->b_rdev
= rdev_tmp
;
1438 bh
->b_rsector
= rsector_tmp
;
1443 buffer_IO_error(bh
);
1449 * internal support functions
1454 * generate "hard disk" name
1456 void lvm_hd_name(char *buf
, int minor
)
1461 if (vg
[VG_BLK(minor
)] == NULL
||
1462 (lv_ptr
= vg
[VG_BLK(minor
)]->lv
[LV_BLK(minor
)]) == NULL
)
1464 len
= strlen(lv_ptr
->lv_name
) - 5;
1465 memcpy(buf
, &lv_ptr
->lv_name
[5], len
);
1473 * this one never should be called...
1475 static void lvm_dummy_device_request(request_queue_t
* t
)
1478 "%s -- oops, got lvm request for %02d:%02d [sector: %lu]\n",
1480 MAJOR(CURRENT
->rq_dev
),
1481 MINOR(CURRENT
->rq_dev
),
1488 * make request function
1490 static int lvm_make_request_fn(request_queue_t
*q
, int rw
, struct buffer_head
*bh
)
1497 * plug device function is a noop because plugging has to happen
1498 * in the queue of the physical blockdevice to allow the
1499 * elevator to do a better job.
1501 static void lvm_plug_device_noop(request_queue_t
*q
, kdev_t dev
) { }
1503 /********************************************************************
1505 * Character device support functions
1507 ********************************************************************/
1509 * character device support function logical volume manager lock
1511 static int lvm_do_lock_lvm(void)
1514 spin_lock(&lvm_lock
);
1515 if (lock
!= 0 && lock
!= current
->pid
) {
1517 printk(KERN_INFO
"lvm_do_lock_lvm: %s is locked by pid %d ...\n",
1520 spin_unlock(&lvm_lock
);
1521 interruptible_sleep_on(&lvm_wait
);
1522 if (current
->sigpending
!= 0)
1524 #ifdef LVM_TOTAL_RESET
1525 if (lvm_reset_spindown
> 0)
1528 goto lock_try_again
;
1530 lock
= current
->pid
;
1531 spin_unlock(&lvm_lock
);
1533 } /* lvm_do_lock_lvm */
1537 * character device support function lock/unlock physical extend
1539 static int lvm_do_pe_lock_unlock(vg_t
*vg_ptr
, void *arg
)
1543 if (vg_ptr
== NULL
) return -ENXIO
;
1544 if (copy_from_user(&pe_lock_req
, arg
,
1545 sizeof(pe_lock_req_t
)) != 0) return -EFAULT
;
1547 switch (pe_lock_req
.lock
) {
1549 for (p
= 0; p
< vg_ptr
->pv_max
; p
++) {
1550 if (vg_ptr
->pv
[p
] != NULL
&&
1551 pe_lock_req
.data
.pv_dev
==
1552 vg_ptr
->pv
[p
]->pv_dev
)
1555 if (p
== vg_ptr
->pv_max
) return -ENXIO
;
1557 pe_lock_req
.lock
= UNLOCK_PE
;
1558 fsync_dev(pe_lock_req
.data
.lv_dev
);
1559 pe_lock_req
.lock
= LOCK_PE
;
1563 pe_lock_req
.lock
= UNLOCK_PE
;
1564 pe_lock_req
.data
.lv_dev
= \
1565 pe_lock_req
.data
.pv_dev
= \
1566 pe_lock_req
.data
.pv_offset
= 0;
1567 wake_up(&lvm_map_wait
);
1578 * character device support function logical extend remap
1580 static int lvm_do_le_remap(vg_t
*vg_ptr
, void *arg
)
1585 if (vg_ptr
== NULL
) return -ENXIO
;
1586 if (copy_from_user(&le_remap_req
, arg
,
1587 sizeof(le_remap_req_t
)) != 0)
1590 for (l
= 0; l
< vg_ptr
->lv_max
; l
++) {
1591 lv_ptr
= vg_ptr
->lv
[l
];
1592 if (lv_ptr
!= NULL
&&
1593 strcmp(lv_ptr
->lv_name
,
1594 le_remap_req
.lv_name
) == 0) {
1595 for (le
= 0; le
< lv_ptr
->lv_allocated_le
;
1597 if (lv_ptr
->lv_current_pe
[le
].dev
==
1598 le_remap_req
.old_dev
&&
1599 lv_ptr
->lv_current_pe
[le
].pe
==
1600 le_remap_req
.old_pe
) {
1601 lv_ptr
->lv_current_pe
[le
].dev
=
1602 le_remap_req
.new_dev
;
1603 lv_ptr
->lv_current_pe
[le
].pe
=
1604 le_remap_req
.new_pe
;
1612 } /* lvm_do_le_remap() */
1616 * character device support function VGDA create
1618 int lvm_do_vg_create(int minor
, void *arg
)
1620 int snaporg_minor
= 0;
1627 if (vg
[VG_CHR(minor
)] != NULL
) return -EPERM
;
1629 if ((vg_ptr
= kmalloc(sizeof(vg_t
),GFP_KERNEL
)) == NULL
) {
1631 "%s -- VG_CREATE: kmalloc error VG at line %d\n",
1632 lvm_name
, __LINE__
);
1635 /* get the volume group structure */
1636 if (copy_from_user(vg_ptr
, arg
, sizeof(vg_t
)) != 0) {
1641 vg_devfs_handle
[vg_ptr
->vg_number
] = devfs_mk_dir(0, vg_ptr
->vg_name
, NULL
);
1642 ch_devfs_handle
[vg_ptr
->vg_number
] = devfs_register(
1643 vg_devfs_handle
[vg_ptr
->vg_number
] , "group",
1644 DEVFS_FL_DEFAULT
, LVM_CHAR_MAJOR
, vg_ptr
->vg_number
,
1645 S_IFCHR
| S_IRUSR
| S_IWUSR
| S_IRGRP
,
1646 &lvm_chr_fops
, NULL
);
1648 /* we are not that active so far... */
1649 vg_ptr
->vg_status
&= ~VG_ACTIVE
;
1650 vg
[VG_CHR(minor
)] = vg_ptr
;
1652 vg
[VG_CHR(minor
)]->pe_allocated
= 0;
1653 if (vg_ptr
->pv_max
> ABS_MAX_PV
) {
1655 "%s -- Can't activate VG: ABS_MAX_PV too small\n",
1658 vg
[VG_CHR(minor
)] = NULL
;
1661 if (vg_ptr
->lv_max
> ABS_MAX_LV
) {
1663 "%s -- Can't activate VG: ABS_MAX_LV too small for %u\n",
1664 lvm_name
, vg_ptr
->lv_max
);
1669 /* get the physical volume structures */
1670 vg_ptr
->pv_act
= vg_ptr
->pv_cur
= 0;
1671 for (p
= 0; p
< vg_ptr
->pv_max
; p
++) {
1672 /* user space address */
1673 if ((pvp
= vg_ptr
->pv
[p
]) != NULL
) {
1674 pv_ptr
= vg_ptr
->pv
[p
] = kmalloc(sizeof(pv_t
),GFP_KERNEL
);
1675 if (pv_ptr
== NULL
) {
1677 "%s -- VG_CREATE: kmalloc error PV at line %d\n",
1678 lvm_name
, __LINE__
);
1679 lvm_do_vg_remove(minor
);
1682 if (copy_from_user(pv_ptr
, pvp
, sizeof(pv_t
)) != 0) {
1683 lvm_do_vg_remove(minor
);
1686 /* We don't need the PE list
1687 in kernel space as with LVs pe_t list (see below) */
1689 pv_ptr
->pe_allocated
= 0;
1690 pv_ptr
->pv_status
= PV_ACTIVE
;
1694 #ifdef LVM_GET_INODE
1695 /* insert a dummy inode for fs_may_mount */
1696 pv_ptr
->inode
= lvm_get_inode(pv_ptr
->pv_dev
);
1701 /* get the logical volume structures */
1703 for (l
= 0; l
< vg_ptr
->lv_max
; l
++) {
1704 /* user space address */
1705 if ((lvp
= vg_ptr
->lv
[l
]) != NULL
) {
1706 if (copy_from_user(&lv
, lvp
, sizeof(lv_t
)) != 0) {
1707 lvm_do_vg_remove(minor
);
1710 vg_ptr
->lv
[l
] = NULL
;
1711 if (lvm_do_lv_create(minor
, lv
.lv_name
, &lv
) != 0) {
1712 lvm_do_vg_remove(minor
);
1718 /* Second path to correct snapshot logical volumes which are not
1719 in place during first path above */
1720 for (l
= 0; l
< vg_ptr
->lv_max
; l
++) {
1721 if ((lv_ptr
= vg_ptr
->lv
[l
]) != NULL
&&
1722 vg_ptr
->lv
[l
]->lv_access
& LV_SNAPSHOT
) {
1723 snaporg_minor
= lv_ptr
->lv_snapshot_minor
;
1724 if (vg_ptr
->lv
[LV_BLK(snaporg_minor
)] != NULL
) {
1725 /* get pointer to original logical volume */
1726 lv_ptr
= vg_ptr
->lv
[l
]->lv_snapshot_org
=
1727 vg_ptr
->lv
[LV_BLK(snaporg_minor
)];
1729 /* set necessary fields of original logical volume */
1730 lv_ptr
->lv_access
|= LV_SNAPSHOT_ORG
;
1731 lv_ptr
->lv_snapshot_minor
= 0;
1732 lv_ptr
->lv_snapshot_org
= lv_ptr
;
1733 lv_ptr
->lv_snapshot_prev
= NULL
;
1735 /* find last snapshot logical volume in the chain */
1736 while (lv_ptr
->lv_snapshot_next
!= NULL
)
1737 lv_ptr
= lv_ptr
->lv_snapshot_next
;
1739 /* set back pointer to this last one in our new logical volume */
1740 vg_ptr
->lv
[l
]->lv_snapshot_prev
= lv_ptr
;
1742 /* last logical volume now points to our new snapshot volume */
1743 lv_ptr
->lv_snapshot_next
= vg_ptr
->lv
[l
];
1745 /* now point to the new one */
1746 lv_ptr
= lv_ptr
->lv_snapshot_next
;
1748 /* set necessary fields of new snapshot logical volume */
1749 lv_ptr
->lv_snapshot_next
= NULL
;
1750 lv_ptr
->lv_current_pe
=
1751 vg_ptr
->lv
[LV_BLK(snaporg_minor
)]->lv_current_pe
;
1752 lv_ptr
->lv_allocated_le
=
1753 vg_ptr
->lv
[LV_BLK(snaporg_minor
)]->lv_allocated_le
;
1754 lv_ptr
->lv_current_le
=
1755 vg_ptr
->lv
[LV_BLK(snaporg_minor
)]->lv_current_le
;
1757 vg_ptr
->lv
[LV_BLK(snaporg_minor
)]->lv_size
;
1764 /* let's go active */
1765 vg_ptr
->vg_status
|= VG_ACTIVE
;
1770 } /* lvm_do_vg_create() */
1774 * character device support function VGDA extend
1776 static int lvm_do_vg_extend(vg_t
*vg_ptr
, void *arg
)
1781 if (vg_ptr
== NULL
) return -ENXIO
;
1782 if (vg_ptr
->pv_cur
< vg_ptr
->pv_max
) {
1783 for (p
= 0; p
< vg_ptr
->pv_max
; p
++) {
1784 if (vg_ptr
->pv
[p
] == NULL
) {
1785 if ((pv_ptr
= vg_ptr
->pv
[p
] = kmalloc(sizeof(pv_t
),GFP_KERNEL
)) == NULL
) {
1787 "%s -- VG_EXTEND: kmalloc error PV at line %d\n",
1788 lvm_name
, __LINE__
);
1791 if (copy_from_user(pv_ptr
, arg
, sizeof(pv_t
)) != 0) {
1793 vg_ptr
->pv
[p
] = NULL
;
1797 pv_ptr
->pv_status
= PV_ACTIVE
;
1798 /* We don't need the PE list
1799 in kernel space like LVs pe_t list */
1805 #ifdef LVM_GET_INODE
1806 /* insert a dummy inode for fs_may_mount */
1807 pv_ptr
->inode
= lvm_get_inode(pv_ptr
->pv_dev
);
1814 } /* lvm_do_vg_extend() */
1818 * character device support function VGDA reduce
1820 static int lvm_do_vg_reduce(vg_t
*vg_ptr
, void *arg
)
1825 if (vg_ptr
== NULL
) return -ENXIO
;
1826 if (copy_from_user(pv_name
, arg
, sizeof(pv_name
)) != 0)
1829 for (p
= 0; p
< vg_ptr
->pv_max
; p
++) {
1830 pv_ptr
= vg_ptr
->pv
[p
];
1831 if (pv_ptr
!= NULL
&&
1832 strcmp(pv_ptr
->pv_name
,
1834 if (pv_ptr
->lv_cur
> 0) return -EPERM
;
1839 #ifdef LVM_GET_INODE
1840 lvm_clear_inode(pv_ptr
->inode
);
1843 /* Make PV pointer array contiguous */
1844 for (; p
< vg_ptr
->pv_max
- 1; p
++)
1845 vg_ptr
->pv
[p
] = vg_ptr
->pv
[p
+ 1];
1846 vg_ptr
->pv
[p
+ 1] = NULL
;
1851 } /* lvm_do_vg_reduce */
1855 * character device support function VGDA remove
1857 static int lvm_do_vg_remove(int minor
)
1860 vg_t
*vg_ptr
= vg
[VG_CHR(minor
)];
1863 if (vg_ptr
== NULL
) return -ENXIO
;
1865 #ifdef LVM_TOTAL_RESET
1866 if (vg_ptr
->lv_open
> 0 && lvm_reset_spindown
== 0)
1868 if (vg_ptr
->lv_open
> 0)
1872 /* let's go inactive */
1873 vg_ptr
->vg_status
&= ~VG_ACTIVE
;
1875 devfs_unregister (ch_devfs_handle
[vg_ptr
->vg_number
]);
1876 devfs_unregister (vg_devfs_handle
[vg_ptr
->vg_number
]);
1879 /* first free snapshot logical volumes */
1880 for (i
= 0; i
< vg_ptr
->lv_max
; i
++) {
1881 if (vg_ptr
->lv
[i
] != NULL
&&
1882 vg_ptr
->lv
[i
]->lv_access
& LV_SNAPSHOT
) {
1883 lvm_do_lv_remove(minor
, NULL
, i
);
1884 current
->state
= TASK_UNINTERRUPTIBLE
;
1885 schedule_timeout(1);
1888 /* then free the rest of the LVs */
1889 for (i
= 0; i
< vg_ptr
->lv_max
; i
++) {
1890 if (vg_ptr
->lv
[i
] != NULL
) {
1891 lvm_do_lv_remove(minor
, NULL
, i
);
1892 current
->state
= TASK_UNINTERRUPTIBLE
;
1893 schedule_timeout(1);
1898 for (i
= 0; i
< vg_ptr
->pv_max
; i
++) {
1899 if ((pv_ptr
= vg_ptr
->pv
[i
]) != NULL
) {
1902 "%s -- kfree %d\n", lvm_name
, __LINE__
);
1904 #ifdef LVM_GET_INODE
1905 lvm_clear_inode(pv_ptr
->inode
);
1908 vg
[VG_CHR(minor
)]->pv
[i
] = NULL
;
1913 printk(KERN_DEBUG
"%s -- kfree %d\n", lvm_name
, __LINE__
);
1916 vg
[VG_CHR(minor
)] = NULL
;
1923 } /* lvm_do_vg_remove() */
1927 * character device support function logical volume create
1929 static int lvm_do_lv_create(int minor
, char *lv_name
, lv_t
*lv
)
1931 int l
, le
, l_new
, p
, size
;
1932 ulong lv_status_save
;
1933 char *lv_tmp
, *lv_buf
;
1934 lv_block_exception_t
*lvbe
= lv
->lv_block_exception
;
1935 vg_t
*vg_ptr
= vg
[VG_CHR(minor
)];
1936 lv_t
*lv_ptr
= NULL
;
1938 if ((pep
= lv
->lv_current_pe
) == NULL
) return -EINVAL
;
1939 if (lv
->lv_chunk_size
> LVM_SNAPSHOT_MAX_CHUNK
)
1942 for (l
= 0; l
< vg_ptr
->lv_max
; l
++) {
1943 if (vg_ptr
->lv
[l
] != NULL
&&
1944 strcmp(vg_ptr
->lv
[l
]->lv_name
, lv_name
) == 0)
1948 /* in case of lv_remove(), lv_create() pair; for eg. lvrename does this */
1950 if (vg_ptr
->lv
[lv
->lv_number
] == NULL
)
1951 l_new
= lv
->lv_number
;
1953 for (l
= 0; l
< vg_ptr
->lv_max
; l
++) {
1954 if (vg_ptr
->lv
[l
] == NULL
)
1955 if (l_new
== -1) l_new
= l
;
1958 if (l_new
== -1) return -EPERM
;
1961 if ((lv_ptr
= kmalloc(sizeof(lv_t
),GFP_KERNEL
)) == NULL
) {;
1962 printk(KERN_CRIT
"%s -- LV_CREATE: kmalloc error LV at line %d\n",
1963 lvm_name
, __LINE__
);
1966 /* copy preloaded LV */
1967 memcpy((char *) lv_ptr
, (char *) lv
, sizeof(lv_t
));
1969 lv_status_save
= lv_ptr
->lv_status
;
1970 lv_ptr
->lv_status
&= ~LV_ACTIVE
;
1971 lv_ptr
->lv_snapshot_org
= \
1972 lv_ptr
->lv_snapshot_prev
= \
1973 lv_ptr
->lv_snapshot_next
= NULL
;
1974 lv_ptr
->lv_block_exception
= NULL
;
1975 init_MUTEX(&lv_ptr
->lv_snapshot_sem
);
1976 vg_ptr
->lv
[l
] = lv_ptr
;
1978 /* get the PE structures from user space if this
1979 is no snapshot logical volume */
1980 if (!(lv_ptr
->lv_access
& LV_SNAPSHOT
)) {
1981 size
= lv_ptr
->lv_allocated_le
* sizeof(pe_t
);
1982 if ((lv_ptr
->lv_current_pe
= vmalloc(size
)) == NULL
) {
1984 "%s -- LV_CREATE: vmalloc error LV_CURRENT_PE of %d Byte "
1986 lvm_name
, size
, __LINE__
);
1988 printk(KERN_DEBUG
"%s -- kfree %d\n", lvm_name
, __LINE__
);
1991 vg
[VG_CHR(minor
)]->lv
[l
] = NULL
;
1994 if (copy_from_user(lv_ptr
->lv_current_pe
, pep
, size
)) {
1995 vfree(lv_ptr
->lv_current_pe
);
1997 vg_ptr
->lv
[l
] = NULL
;
2000 /* correct the PE count in PVs */
2001 for (le
= 0; le
< lv_ptr
->lv_allocated_le
; le
++) {
2002 vg_ptr
->pe_allocated
++;
2003 for (p
= 0; p
< vg_ptr
->pv_cur
; p
++) {
2004 if (vg_ptr
->pv
[p
]->pv_dev
==
2005 lv_ptr
->lv_current_pe
[le
].dev
)
2006 vg_ptr
->pv
[p
]->pe_allocated
++;
2010 /* Get snapshot exception data and block list */
2012 lv_ptr
->lv_snapshot_org
=
2013 vg_ptr
->lv
[LV_BLK(lv_ptr
->lv_snapshot_minor
)];
2014 if (lv_ptr
->lv_snapshot_org
!= NULL
) {
2015 size
= lv_ptr
->lv_remap_end
* sizeof(lv_block_exception_t
);
2016 if ((lv_ptr
->lv_block_exception
= vmalloc(size
)) == NULL
) {
2018 "%s -- lvm_do_lv_create: vmalloc error LV_BLOCK_EXCEPTION "
2019 "of %d byte at line %d\n",
2020 lvm_name
, size
, __LINE__
);
2022 printk(KERN_DEBUG
"%s -- kfree %d\n", lvm_name
, __LINE__
);
2025 vg_ptr
->lv
[l
] = NULL
;
2028 if (copy_from_user(lv_ptr
->lv_block_exception
, lvbe
, size
)) {
2029 vfree(lv_ptr
->lv_block_exception
);
2031 vg
[VG_CHR(minor
)]->lv
[l
] = NULL
;
2034 /* get pointer to original logical volume */
2035 lv_ptr
= lv_ptr
->lv_snapshot_org
;
2037 lv_ptr
->lv_snapshot_minor
= 0;
2038 lv_ptr
->lv_snapshot_org
= lv_ptr
;
2039 lv_ptr
->lv_snapshot_prev
= NULL
;
2040 /* walk thrugh the snapshot list */
2041 while (lv_ptr
->lv_snapshot_next
!= NULL
)
2042 lv_ptr
= lv_ptr
->lv_snapshot_next
;
2043 /* now lv_ptr points to the last existing snapshot in the chain */
2044 vg_ptr
->lv
[l
]->lv_snapshot_prev
= lv_ptr
;
2045 /* our new one now back points to the previous last in the chain */
2046 lv_ptr
= vg_ptr
->lv
[l
];
2047 /* now lv_ptr points to our new last snapshot logical volume */
2048 lv_ptr
->lv_snapshot_org
= lv_ptr
->lv_snapshot_prev
->lv_snapshot_org
;
2049 lv_ptr
->lv_snapshot_next
= NULL
;
2050 lv_ptr
->lv_current_pe
= lv_ptr
->lv_snapshot_org
->lv_current_pe
;
2051 lv_ptr
->lv_allocated_le
= lv_ptr
->lv_snapshot_org
->lv_allocated_le
;
2052 lv_ptr
->lv_current_le
= lv_ptr
->lv_snapshot_org
->lv_current_le
;
2053 lv_ptr
->lv_size
= lv_ptr
->lv_snapshot_org
->lv_size
;
2054 lv_ptr
->lv_stripes
= lv_ptr
->lv_snapshot_org
->lv_stripes
;
2055 lv_ptr
->lv_stripesize
= lv_ptr
->lv_snapshot_org
->lv_stripesize
;
2057 int err
= lvm_snapshot_alloc(lv_ptr
);
2060 vfree(lv_ptr
->lv_block_exception
);
2062 vg
[VG_CHR(minor
)]->lv
[l
] = NULL
;
2067 vfree(lv_ptr
->lv_block_exception
);
2069 vg_ptr
->lv
[l
] = NULL
;
2073 kfree(vg_ptr
->lv
[l
]);
2074 vg_ptr
->lv
[l
] = NULL
;
2077 } /* if ( vg[VG_CHR(minor)]->lv[l]->lv_access & LV_SNAPSHOT) */
2079 lv_ptr
= vg_ptr
->lv
[l
];
2080 lvm_gendisk
.part
[MINOR(lv_ptr
->lv_dev
)].start_sect
= 0;
2081 lvm_gendisk
.part
[MINOR(lv_ptr
->lv_dev
)].nr_sects
= lv_ptr
->lv_size
;
2082 lvm_size
[MINOR(lv_ptr
->lv_dev
)] = lv_ptr
->lv_size
>> 1;
2083 vg_lv_map
[MINOR(lv_ptr
->lv_dev
)].vg_number
= vg_ptr
->vg_number
;
2084 vg_lv_map
[MINOR(lv_ptr
->lv_dev
)].lv_number
= lv_ptr
->lv_number
;
2085 read_ahead
[MAJOR_NR
] = lv_ptr
->lv_read_ahead
= LVM_CORRECT_READ_AHEAD(lv_ptr
->lv_read_ahead
);
2087 lv_ptr
->lv_status
= lv_status_save
;
2089 strtok(lv
->lv_name
, "/"); /* /dev */
2091 while((lv_tmp
= strtok(NULL
, "/")) != NULL
)
2094 lv_devfs_handle
[lv
->lv_number
] = devfs_register(
2095 vg_devfs_handle
[vg_ptr
->vg_number
], lv_buf
,
2096 DEVFS_FL_DEFAULT
, LVM_BLK_MAJOR
, lv
->lv_number
,
2097 S_IFBLK
| S_IRUSR
| S_IWUSR
| S_IRGRP
,
2098 &lvm_blk_dops
, NULL
);
2100 /* optionally add our new snapshot LV */
2101 if (lv_ptr
->lv_access
& LV_SNAPSHOT
) {
2102 /* sync the original logical volume */
2103 fsync_dev(lv_ptr
->lv_snapshot_org
->lv_dev
);
2104 /* put ourselve into the chain */
2105 lv_ptr
->lv_snapshot_prev
->lv_snapshot_next
= lv_ptr
;
2106 lv_ptr
->lv_snapshot_org
->lv_access
|= LV_SNAPSHOT_ORG
;
2109 } /* lvm_do_lv_create() */
2113 * character device support function logical volume remove
2115 static int lvm_do_lv_remove(int minor
, char *lv_name
, int l
)
2118 vg_t
*vg_ptr
= vg
[VG_CHR(minor
)];
2122 for (l
= 0; l
< vg_ptr
->lv_max
; l
++) {
2123 if (vg_ptr
->lv
[l
] != NULL
&&
2124 strcmp(vg_ptr
->lv
[l
]->lv_name
, lv_name
) == 0) {
2129 if (l
== vg_ptr
->lv_max
) return -ENXIO
;
2131 lv_ptr
= vg_ptr
->lv
[l
];
2132 #ifdef LVM_TOTAL_RESET
2133 if (lv_ptr
->lv_open
> 0 && lvm_reset_spindown
== 0)
2135 if (lv_ptr
->lv_open
> 0)
2139 /* check for deletion of snapshot source while
2140 snapshot volume still exists */
2141 if ((lv_ptr
->lv_access
& LV_SNAPSHOT_ORG
) &&
2142 lv_ptr
->lv_snapshot_next
!= NULL
)
2145 lv_ptr
->lv_status
|= LV_SPINDOWN
;
2147 /* sync the buffers */
2148 fsync_dev(lv_ptr
->lv_dev
);
2150 lv_ptr
->lv_status
&= ~LV_ACTIVE
;
2152 /* invalidate the buffers */
2153 invalidate_buffers(lv_ptr
->lv_dev
);
2155 /* reset generic hd */
2156 lvm_gendisk
.part
[MINOR(lv_ptr
->lv_dev
)].start_sect
= -1;
2157 lvm_gendisk
.part
[MINOR(lv_ptr
->lv_dev
)].nr_sects
= 0;
2158 lvm_size
[MINOR(lv_ptr
->lv_dev
)] = 0;
2160 /* reset VG/LV mapping */
2161 vg_lv_map
[MINOR(lv_ptr
->lv_dev
)].vg_number
= ABS_MAX_VG
;
2162 vg_lv_map
[MINOR(lv_ptr
->lv_dev
)].lv_number
= -1;
2164 /* correct the PE count in PVs if this is no snapshot logical volume */
2165 if (!(lv_ptr
->lv_access
& LV_SNAPSHOT
)) {
2166 /* only if this is no snapshot logical volume because
2167 we share the lv_current_pe[] structs with the
2168 original logical volume */
2169 for (le
= 0; le
< lv_ptr
->lv_allocated_le
; le
++) {
2170 vg_ptr
->pe_allocated
--;
2171 for (p
= 0; p
< vg_ptr
->pv_cur
; p
++) {
2172 if (vg_ptr
->pv
[p
]->pv_dev
==
2173 lv_ptr
->lv_current_pe
[le
].dev
)
2174 vg_ptr
->pv
[p
]->pe_allocated
--;
2177 vfree(lv_ptr
->lv_current_pe
);
2180 /* remove this snapshot logical volume from the chain */
2181 lv_ptr
->lv_snapshot_prev
->lv_snapshot_next
= lv_ptr
->lv_snapshot_next
;
2182 if (lv_ptr
->lv_snapshot_next
!= NULL
) {
2183 lv_ptr
->lv_snapshot_next
->lv_snapshot_prev
=
2184 lv_ptr
->lv_snapshot_prev
;
2186 /* no more snapshots? */
2187 if (lv_ptr
->lv_snapshot_org
->lv_snapshot_next
== NULL
)
2188 lv_ptr
->lv_snapshot_org
->lv_access
&= ~LV_SNAPSHOT_ORG
;
2189 lvm_snapshot_release(lv_ptr
);
2192 devfs_unregister(lv_devfs_handle
[lv_ptr
->lv_number
]);
2195 printk(KERN_DEBUG
"%s -- kfree %d\n", lvm_name
, __LINE__
);
2198 vg_ptr
->lv
[l
] = NULL
;
2201 } /* lvm_do_lv_remove() */
2205 * character device support function logical volume extend / reduce
2207 static int lvm_do_lv_extend_reduce(int minor
, char *lv_name
, lv_t
*lv
)
2209 int l
, le
, p
, size
, old_allocated_le
;
2210 uint32_t end
, lv_status_save
;
2211 vg_t
*vg_ptr
= vg
[VG_CHR(minor
)];
2215 if ((pep
= lv
->lv_current_pe
) == NULL
) return -EINVAL
;
2217 for (l
= 0; l
< vg_ptr
->lv_max
; l
++) {
2218 if (vg_ptr
->lv
[l
] != NULL
&&
2219 strcmp(vg_ptr
->lv
[l
]->lv_name
, lv_name
) == 0)
2222 if (l
== vg_ptr
->lv_max
) return -ENXIO
;
2223 lv_ptr
= vg_ptr
->lv
[l
];
2225 /* check for active snapshot */
2226 if (lv
->lv_access
& (LV_SNAPSHOT
| LV_SNAPSHOT_ORG
)) return -EPERM
;
2228 if ((pe
= vmalloc(size
= lv
->lv_current_le
* sizeof(pe_t
))) == NULL
) {
2230 "%s -- lvm_do_lv_extend_reduce: vmalloc error LV_CURRENT_PE "
2231 "of %d Byte at line %d\n",
2232 lvm_name
, size
, __LINE__
);
2235 /* get the PE structures from user space */
2236 if (copy_from_user(pe
, pep
, size
)) {
2243 "%s -- fsync_dev and "
2244 "invalidate_buffers for %s [%s] in %s\n",
2245 lvm_name
, lv_ptr
->lv_name
,
2246 kdevname(lv_ptr
->lv_dev
),
2250 lv_ptr
->lv_status
|= LV_SPINDOWN
;
2251 fsync_dev(lv_ptr
->lv_dev
);
2252 lv_ptr
->lv_status
&= ~LV_ACTIVE
;
2253 invalidate_buffers(lv_ptr
->lv_dev
);
2255 /* reduce allocation counters on PV(s) */
2256 for (le
= 0; le
< lv_ptr
->lv_allocated_le
; le
++) {
2257 vg_ptr
->pe_allocated
--;
2258 for (p
= 0; p
< vg_ptr
->pv_cur
; p
++) {
2259 if (vg_ptr
->pv
[p
]->pv_dev
==
2260 lv_ptr
->lv_current_pe
[le
].dev
) {
2261 vg_ptr
->pv
[p
]->pe_allocated
--;
2268 /* save pointer to "old" lv/pe pointer array */
2269 pep1
= lv_ptr
->lv_current_pe
;
2270 end
= lv_ptr
->lv_current_le
;
2272 /* save open counter */
2273 lv_open
= lv_ptr
->lv_open
;
2275 /* save # of old allocated logical extents */
2276 old_allocated_le
= lv_ptr
->lv_allocated_le
;
2278 /* copy preloaded LV */
2279 lv_status_save
= lv
->lv_status
;
2280 lv
->lv_status
|= LV_SPINDOWN
;
2281 lv
->lv_status
&= ~LV_ACTIVE
;
2282 memcpy((char *) lv_ptr
, (char *) lv
, sizeof(lv_t
));
2283 lv_ptr
->lv_current_pe
= pe
;
2284 lv_ptr
->lv_open
= lv_open
;
2286 /* save availiable i/o statistic data */
2287 /* linear logical volume */
2288 if (lv_ptr
->lv_stripes
< 2) {
2289 /* Check what last LE shall be used */
2290 if (end
> lv_ptr
->lv_current_le
) end
= lv_ptr
->lv_current_le
;
2291 for (le
= 0; le
< end
; le
++) {
2292 lv_ptr
->lv_current_pe
[le
].reads
= pep1
[le
].reads
;
2293 lv_ptr
->lv_current_pe
[le
].writes
= pep1
[le
].writes
;
2295 /* striped logical volume */
2297 uint i
, j
, source
, dest
, end
, old_stripe_size
, new_stripe_size
;
2299 old_stripe_size
= old_allocated_le
/ lv_ptr
->lv_stripes
;
2300 new_stripe_size
= lv_ptr
->lv_allocated_le
/ lv_ptr
->lv_stripes
;
2301 end
= old_stripe_size
;
2302 if (end
> new_stripe_size
) end
= new_stripe_size
;
2303 for (i
= source
= dest
= 0;
2304 i
< lv_ptr
->lv_stripes
; i
++) {
2305 for (j
= 0; j
< end
; j
++) {
2306 lv_ptr
->lv_current_pe
[dest
+ j
].reads
=
2307 pep1
[source
+ j
].reads
;
2308 lv_ptr
->lv_current_pe
[dest
+ j
].writes
=
2309 pep1
[source
+ j
].writes
;
2311 source
+= old_stripe_size
;
2312 dest
+= new_stripe_size
;
2319 /* extend the PE count in PVs */
2320 for (le
= 0; le
< lv_ptr
->lv_allocated_le
; le
++) {
2321 vg_ptr
->pe_allocated
++;
2322 for (p
= 0; p
< vg_ptr
->pv_cur
; p
++) {
2323 if (vg_ptr
->pv
[p
]->pv_dev
==
2324 vg_ptr
->lv
[l
]->lv_current_pe
[le
].dev
) {
2325 vg_ptr
->pv
[p
]->pe_allocated
++;
2331 lvm_gendisk
.part
[MINOR(lv_ptr
->lv_dev
)].start_sect
= 0;
2332 lvm_gendisk
.part
[MINOR(lv_ptr
->lv_dev
)].nr_sects
= lv_ptr
->lv_size
;
2333 lvm_size
[MINOR(lv_ptr
->lv_dev
)] = lv_ptr
->lv_size
>> 1;
2334 /* vg_lv_map array doesn't have to be changed here */
2336 read_ahead
[MAJOR_NR
] = lv_ptr
->lv_read_ahead
= LVM_CORRECT_READ_AHEAD(lv_ptr
->lv_read_ahead
);
2337 lv_ptr
->lv_status
= lv_status_save
;
2340 } /* lvm_do_lv_extend_reduce() */
2344 * character device support function logical volume status by name
2346 static int lvm_do_lv_status_byname(vg_t
*vg_ptr
, void *arg
)
2352 lv_status_byname_req_t lv_status_byname_req
;
2354 if (vg_ptr
== NULL
) return -ENXIO
;
2355 if (copy_from_user(&lv_status_byname_req
, arg
,
2356 sizeof(lv_status_byname_req_t
)) != 0)
2359 if (lv_status_byname_req
.lv
== NULL
) return -EINVAL
;
2360 if (copy_from_user(&lv
, lv_status_byname_req
.lv
,
2364 for (l
= 0; l
< vg_ptr
->lv_max
; l
++) {
2365 lv_ptr
= vg_ptr
->lv
[l
];
2366 if (lv_ptr
!= NULL
&&
2367 strcmp(lv_ptr
->lv_name
,
2368 lv_status_byname_req
.lv_name
) == 0) {
2369 if (copy_to_user(lv_status_byname_req
.lv
,
2374 if (lv
.lv_current_pe
!= NULL
) {
2375 size
= lv_ptr
->lv_allocated_le
*
2377 if (copy_to_user(lv
.lv_current_pe
,
2378 lv_ptr
->lv_current_pe
,
2386 } /* lvm_do_lv_status_byname() */
2390 * character device support function logical volume status by index
2392 static int lvm_do_lv_status_byindex(vg_t
*vg_ptr
,void *arg
)
2397 lv_status_byindex_req_t lv_status_byindex_req
;
2399 if (vg_ptr
== NULL
) return -ENXIO
;
2400 if (copy_from_user(&lv_status_byindex_req
, arg
,
2401 sizeof(lv_status_byindex_req
)) != 0)
2404 if ((lvp
= lv_status_byindex_req
.lv
) == NULL
)
2406 if ( ( lv_ptr
= vg_ptr
->lv
[lv_status_byindex_req
.lv_index
]) == NULL
)
2409 if (copy_from_user(&lv
, lvp
, sizeof(lv_t
)) != 0)
2412 if (copy_to_user(lvp
, lv_ptr
, sizeof(lv_t
)) != 0)
2415 if (lv
.lv_current_pe
!= NULL
) {
2416 size
= lv_ptr
->lv_allocated_le
* sizeof(pe_t
);
2417 if (copy_to_user(lv
.lv_current_pe
,
2418 lv_ptr
->lv_current_pe
,
2423 } /* lvm_do_lv_status_byindex() */
2427 * character device support function physical volume change
2429 static int lvm_do_pv_change(vg_t
*vg_ptr
, void *arg
)
2433 #ifdef LVM_GET_INODE
2434 struct inode
*inode_sav
;
2437 if (vg_ptr
== NULL
) return -ENXIO
;
2438 if (copy_from_user(&pv_change_req
, arg
,
2439 sizeof(pv_change_req
)) != 0)
2442 for (p
= 0; p
< vg_ptr
->pv_max
; p
++) {
2443 pv_ptr
= vg_ptr
->pv
[p
];
2444 if (pv_ptr
!= NULL
&&
2445 strcmp(pv_ptr
->pv_name
,
2446 pv_change_req
.pv_name
) == 0) {
2447 #ifdef LVM_GET_INODE
2448 inode_sav
= pv_ptr
->inode
;
2450 if (copy_from_user(pv_ptr
,
2455 /* We don't need the PE list
2456 in kernel space as with LVs pe_t list */
2458 #ifdef LVM_GET_INODE
2459 pv_ptr
->inode
= inode_sav
;
2465 } /* lvm_do_pv_change() */
2468 * character device support function get physical volume status
2470 static int lvm_do_pv_status(vg_t
*vg_ptr
, void *arg
)
2475 if (vg_ptr
== NULL
) return -ENXIO
;
2476 if (copy_from_user(&pv_status_req
, arg
,
2477 sizeof(pv_status_req
)) != 0)
2480 for (p
= 0; p
< vg_ptr
->pv_max
; p
++) {
2481 pv_ptr
= vg_ptr
->pv
[p
];
2482 if (pv_ptr
!= NULL
&&
2483 strcmp(pv_ptr
->pv_name
,
2484 pv_status_req
.pv_name
) == 0) {
2485 if (copy_to_user(pv_status_req
.pv
,
2493 } /* lvm_do_pv_status() */
2497 * support function initialize gendisk variables
2500 __initfunc(void lvm_geninit(struct gendisk
*lvm_gdisk
))
2503 lvm_geninit(struct gendisk
*lvm_gdisk
)
2508 #ifdef DEBUG_GENDISK
2509 printk(KERN_DEBUG
"%s -- lvm_gendisk\n", lvm_name
);
2512 for (i
= 0; i
< MAX_LV
; i
++) {
2513 lvm_gendisk
.part
[i
].start_sect
= -1; /* avoid partition check */
2514 lvm_size
[i
] = lvm_gendisk
.part
[i
].nr_sects
= 0;
2515 lvm_blocksizes
[i
] = BLOCK_SIZE
;
2518 blksize_size
[MAJOR_NR
] = lvm_blocksizes
;
2519 blk_size
[MAJOR_NR
] = lvm_size
;
2522 } /* lvm_gen_init() */
2525 #ifdef LVM_GET_INODE
2527 * support function to get an empty inode
2529 * Gets an empty inode to be inserted into the inode hash,
2530 * so that a physical volume can't be mounted.
2531 * This is analog to drivers/block/md.c
2533 * Is this the real thing?
2535 * No, it's bollocks. md.c tries to do a bit different thing that might
2536 * _somewhat_ work eons ago. Neither does any good these days. mount() couldn't
2537 * care less for icache (it cares only for ->s_root->d_count and if we want
2538 * loopback mounts even that will stop). BTW, with the form used here mount()
2539 * would have to scan the _whole_ icache to detect the attempt - how on the
2540 * Earth could it guess the i_ino of your dummy inode? Official line on the
2541 * exclusion between mount()/swapon()/open()/etc. is Just Don't Do It(tm).
2542 * If you can convince Linus that it's worth changing - fine, then you'll need
2543 * to do blkdev_get()/blkdev_put(). Until then...
2545 struct inode
*lvm_get_inode(int dev
)
2547 struct inode
*inode_this
= NULL
;
2549 /* Lock the device by inserting a dummy inode. */
2550 inode_this
= get_empty_inode();
2551 inode_this
->i_dev
= dev
;
2552 insert_inode_hash(inode_this
);
2558 * support function to clear an inode
2561 void lvm_clear_inode(struct inode
*inode
)
2564 inode
->i_state
|= I_FREEING
;
2569 #endif /* #ifdef LVM_GET_INODE */