- pre5:
[davej-history.git] / drivers / block / lvm.c
blobfc762c54ff4998138182ee0662ad52360bd3d2c7
1 /*
2 * kernel/lvm.c
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)
15 * any later version.
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.
30 * Changelog
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
50 * with 2.0.x
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()
68 * to lvm_chr_ioctl()
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()
79 * and lvm_blk_write()
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
101 * - lvm_chr_ioctl
102 * - LV_STATUS_BYINDEX
103 * - LV_STATUS_BYNAME
104 * - lvm_do_lv_create
105 * - lvm_do_lv_remove
106 * - lvm_map
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>
139 #ifdef MODVERSIONS
140 #undef MODULE
141 #define MODULE
142 #include <linux/modversions.h>
143 #endif
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>
166 #endif
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))
180 #ifndef WRITEA
181 # define WRITEA WRITE
182 #endif
185 * External function prototypes
187 #ifdef MODULE
188 int init_module(void);
189 void cleanup_module(void);
190 #else
191 extern int lvm_init(void);
192 #endif
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) =
213 &lvm_proc_get_info;
214 #endif
216 #ifdef LVM_HD_NAME
217 void lvm_hd_name(char *, int);
218 #endif
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 *);
233 #ifdef LVM_HD_NAME
234 extern void (*lvm_hd_name_ptr) (char *, int);
235 #endif
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 *);
252 #ifdef LVM_GET_INODE
253 static struct inode *lvm_get_inode(int);
254 void lvm_clear_inode(struct inode *);
255 #endif
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 */
268 typedef struct {
269 int vg_number;
270 int lv_number;
271 } vg_lv_map_t;
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;
285 #endif
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;
291 static int lock = 0;
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 =
309 owner: THIS_MODULE,
310 open: lvm_chr_open,
311 release: lvm_chr_close,
312 ioctl: lvm_chr_ioctl,
315 static struct block_device_operations lvm_blk_dops =
317 open: lvm_blk_open,
318 release: lvm_blk_close,
319 ioctl: lvm_blk_ioctl
322 /* gendisk structures */
323 static struct hd_struct lvm_hd_struct[MAX_LV];
324 static int lvm_blocksizes[MAX_LV] =
325 {0,};
326 static int lvm_size[MAX_LV] =
327 {0,};
328 static struct gendisk lvm_gendisk =
330 MAJOR_NR, /* major # */
331 LVM_NAME, /* name of major */
332 0, /* number of times minor is shifted
333 to get real minor */
334 1, /* maximum partitions per device */
335 lvm_hd_struct, /* partition table */
336 lvm_size, /* device size in blocks, copied
337 to block_size[] */
338 MAX_LV, /* number or real devices */
339 NULL, /* internal */
340 NULL, /* pointer to next gendisk struct (internal) */
344 #ifdef MODULE
346 * Module initialization...
348 int init_module(void)
349 #else
351 * Driver initialization...
353 #ifdef __initfunc
354 __initfunc(int lvm_init(void))
355 #else
356 int __init lvm_init(void)
357 #endif
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);
364 return -EIO;
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);
370 return -EIO;
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);
381 #endif
383 lvm_init_vars();
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;
395 } else {
396 gendisk_head = &lvm_gendisk;
397 lvm_gendisk.next = NULL;
400 #ifdef LVM_HD_NAME
401 /* reference from drivers/block/genhd.c */
402 lvm_hd_name_ptr = lvm_hd_name;
403 #endif
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);
413 printk(KERN_INFO
414 "%s%s -- "
415 #ifdef MODULE
416 "Module"
417 #else
418 "Driver"
419 #endif
420 " successfully initialized\n",
421 lvm_version, lvm_name);
423 return 0;
424 } /* init_module() / lvm_init() */
427 #ifdef MODULE
429 * Module cleanup...
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)
448 break;
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);
461 #endif
463 #ifdef LVM_HD_NAME
464 /* reference from linux/drivers/block/genhd.c */
465 lvm_hd_name_ptr = NULL;
466 #endif
468 printk(KERN_INFO "%s -- Module successfully deactivated\n", lvm_name);
470 return;
471 } /* void cleanup_module() */
472 #endif /* #ifdef MODULE */
476 * support function to initialize lvm variables
478 #ifdef __initfunc
479 __initfunc(void lvm_init_vars(void))
480 #else
481 void __init lvm_init_vars(void)
482 #endif
484 int v;
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;
503 return;
504 } /* lvm_init_vars() */
507 /********************************************************************
509 * Character device functions
511 ********************************************************************/
514 * character device open routine
516 static int lvm_chr_open(struct inode *inode,
517 struct file *file)
519 int minor = MINOR(inode->i_rdev);
521 #ifdef DEBUG
522 printk(KERN_DEBUG
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);
525 #endif
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++;
534 return 0;
535 } /* lvm_chr_open() */
539 * character device i/o-control routine
541 * Only one changing process can do changing ioctl at one time,
542 * others will block.
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;
551 lv_t lv;
552 vg_t* vg_ptr = vg[VG_CHR(minor)];
554 /* otherwise cc will complain about unused variables */
555 (void) lvm_lock;
558 #ifdef DEBUG_IOCTL
559 printk(KERN_DEBUG
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);
563 #endif
565 #ifdef LVM_TOTAL_RESET
566 if (lvm_reset_spindown > 0) return -EACCES;
567 #endif
569 /* Main command switch */
570 switch (command) {
571 case LVM_LOCK_LVM:
572 /* lock the LVM */
573 return lvm_do_lock_lvm();
575 case LVM_GET_IOP_VERSION:
576 /* check lvm version to ensure driver/tools+lib
577 interoperability */
578 if (copy_to_user(arg, &lvm_iop_version, sizeof(ushort)) != 0)
579 return -EFAULT;
580 return 0;
582 #ifdef LVM_TOTAL_RESET
583 case LVM_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);
590 #ifdef MODULE
591 while (GET_USE_COUNT(&__this_module) < 1)
592 MOD_INC_USE_COUNT;
593 while (GET_USE_COUNT(&__this_module) > 1)
594 MOD_DEC_USE_COUNT;
595 #endif /* MODULE */
596 lock = 0; /* release lock */
597 wake_up_interruptible(&lvm_wait);
598 return 0;
599 #endif /* LVM_TOTAL_RESET */
602 case LE_REMAP:
603 /* remap a logical extent (after moving the physical extent) */
604 return lvm_do_le_remap(vg_ptr,arg);
606 case PE_LOCK_UNLOCK:
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);
611 case VG_CREATE:
612 /* create a VGDA */
613 return lvm_do_vg_create(minor, arg);
615 case VG_REMOVE:
616 /* remove an inactive VGDA */
617 return lvm_do_vg_remove(minor);
619 case VG_EXTEND:
620 /* extend a volume group */
621 return lvm_do_vg_extend(vg_ptr,arg);
623 case VG_REDUCE:
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)
632 return -EFAULT;
634 if (extendable == VG_EXTENDABLE ||
635 extendable == ~VG_EXTENDABLE) {
636 if (extendable == VG_EXTENDABLE)
637 vg_ptr->vg_status |= VG_EXTENDABLE;
638 else
639 vg_ptr->vg_status &= ~VG_EXTENDABLE;
640 } else return -EINVAL;
641 return 0;
644 case VG_STATUS:
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)
648 return -EFAULT;
649 return 0;
652 case VG_STATUS_GET_COUNT:
653 /* get volume group count */
654 if (copy_to_user(arg, &vg_count, sizeof(vg_count)) != 0)
655 return -EFAULT;
656 return 0;
659 case VG_STATUS_GET_NAMELIST:
660 /* get volume group count */
661 for (l = v = 0; v < ABS_MAX_VG; v++) {
662 if (vg[v] != NULL) {
663 if (copy_to_user(arg + l++ * NAME_LEN,
664 vg[v]->vg_name,
665 NAME_LEN) != 0)
666 return -EFAULT;
669 return 0;
672 case LV_CREATE:
673 case LV_REMOVE:
674 case LV_EXTEND:
675 case LV_REDUCE:
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)
679 return -EFAULT;
681 if (command != LV_REMOVE) {
682 if (copy_from_user(&lv, lv_req.lv, sizeof(lv_t)) != 0)
683 return -EFAULT;
685 switch (command) {
686 case LV_CREATE:
687 return lvm_do_lv_create(minor, lv_req.lv_name, &lv);
689 case LV_REMOVE:
690 return lvm_do_lv_remove(minor, lv_req.lv_name, -1);
692 case LV_EXTEND:
693 case LV_REDUCE:
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);
706 case PV_CHANGE:
707 /* change a physical volume */
708 return lvm_do_pv_change(vg_ptr,arg);
710 case PV_STATUS:
711 /* get physical volume data (pv_t structure only) */
712 return lvm_do_pv_status(vg_ptr,arg);
714 case PV_FLUSH:
715 /* physical volume buffer flush/invalidate */
716 if (copy_from_user(&pv_flush_req, arg,
717 sizeof(pv_flush_req)) != 0)
718 return -EFAULT;
720 for ( v = 0; v < ABS_MAX_VG; v++) {
721 unsigned int p;
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);
729 return 0;
733 return 0;
735 default:
736 printk(KERN_WARNING
737 "%s -- lvm_chr_ioctl: unknown command %x\n",
738 lvm_name, command);
739 return -EINVAL;
742 return 0;
743 } /* lvm_chr_ioctl */
747 * character device close routine
749 static int lvm_chr_close(struct inode *inode, struct file *file)
751 #ifdef DEBUG
752 int minor = MINOR(inode->i_rdev);
753 printk(KERN_DEBUG
754 "%s -- lvm_chr_close VG#: %d\n", lvm_name, VG_CHR(minor));
755 #endif
757 lock_kernel();
758 #ifdef LVM_TOTAL_RESET
759 if (lvm_reset_spindown > 0) {
760 lvm_reset_spindown = 0;
761 lvm_chr_open_count = 1;
763 #endif
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);
770 unlock_kernel();
772 return 0;
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);
789 lv_t *lv_ptr;
790 vg_t *vg_ptr = vg[VG_BLK(minor)];
792 #ifdef DEBUG_LVM_BLK_OPEN
793 printk(KERN_DEBUG
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);
796 #endif
798 #ifdef LVM_TOTAL_RESET
799 if (lvm_reset_spindown > 0)
800 return -EPERM;
801 #endif
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++;
820 lv_ptr->lv_open++;
822 MOD_INC_USE_COUNT;
824 #ifdef DEBUG_LVM_BLK_OPEN
825 printk(KERN_DEBUG
826 "%s -- lvm_blk_open MINOR: %d VG#: %d LV#: %d size: %d\n",
827 lvm_name, minor, VG_BLK(minor), LV_BLK(minor),
828 lv_ptr->lv_size);
829 #endif
831 return 0;
833 return -ENXIO;
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;
849 #ifdef DEBUG_IOCTL
850 printk(KERN_DEBUG
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));
855 #endif
857 switch (command) {
858 case BLKGETSIZE:
859 /* return device size */
860 #ifdef DEBUG_IOCTL
861 printk(KERN_DEBUG
862 "%s -- lvm_blk_ioctl -- BLKGETSIZE: %u\n",
863 lvm_name, lv_ptr->lv_size);
864 #endif
865 if (put_user(lv_ptr->lv_size, (long *)arg))
866 return -EFAULT;
867 break;
870 case BLKFLSBUF:
871 /* flush buffer cache */
872 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
874 #ifdef DEBUG_IOCTL
875 printk(KERN_DEBUG
876 "%s -- lvm_blk_ioctl -- BLKFLSBUF\n", lvm_name);
877 #endif
878 fsync_dev(inode->i_rdev);
879 invalidate_buffers(inode->i_rdev);
880 break;
883 case BLKRASET:
884 /* set read ahead for block device */
885 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
887 #ifdef DEBUG_IOCTL
888 printk(KERN_DEBUG
889 "%s -- lvm_blk_ioctl -- BLKRASET: %d sectors for %02X:%02X\n",
890 lvm_name, (long) arg, MAJOR(inode->i_rdev), minor);
891 #endif
892 if ((long) arg < LVM_MIN_READ_AHEAD ||
893 (long) arg > LVM_MAX_READ_AHEAD)
894 return -EINVAL;
895 read_ahead[MAJOR_NR] = lv_ptr->lv_read_ahead = (long) arg;
896 break;
899 case BLKRAGET:
900 /* get current read ahead setting */
901 #ifdef DEBUG_IOCTL
902 printk(KERN_DEBUG
903 "%s -- lvm_blk_ioctl -- BLKRAGET\n", lvm_name);
904 #endif
905 if (put_user(lv_ptr->lv_read_ahead, (long *)arg))
906 return -EFAULT;
907 break;
910 case HDIO_GETGEO:
911 /* get disk geometry */
912 #ifdef DEBUG_IOCTL
913 printk(KERN_DEBUG
914 "%s -- lvm_blk_ioctl -- HDIO_GETGEO\n", lvm_name);
915 #endif
916 if (hd == NULL)
917 return -EINVAL;
919 unsigned char heads = 64;
920 unsigned char sectors = 32;
921 long start = 0;
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, &sectors,
927 sizeof(sectors)) != 0 ||
928 copy_to_user((short *) &hd->cylinders,
929 &cylinders, sizeof(cylinders)) != 0 ||
930 copy_to_user((long *) &hd->start, &start,
931 sizeof(start)) != 0)
932 return -EFAULT;
935 #ifdef DEBUG_IOCTL
936 printk(KERN_DEBUG
937 "%s -- lvm_blk_ioctl -- cylinders: %d\n",
938 lvm_name, lv_ptr->lv_size / heads / sectors);
939 #endif
940 break;
943 case LV_SET_ACCESS:
944 /* set access flags of a logical volume */
945 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
946 lv_ptr->lv_access = (ulong) arg;
947 break;
950 case LV_SET_STATUS:
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)
954 return -EPERM;
955 lv_ptr->lv_status = (ulong) arg;
956 break;
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;
963 break;
966 default:
967 printk(KERN_WARNING
968 "%s -- lvm_blk_ioctl: unknown command %d\n",
969 lvm_name, command);
970 return -EINVAL;
973 return 0;
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)];
986 #ifdef DEBUG
987 printk(KERN_DEBUG
988 "%s -- lvm_blk_close MINOR: %d VG#: %d LV#: %d\n",
989 lvm_name, minor, VG_BLK(minor), LV_BLK(minor));
990 #endif
992 sync_dev(inode->i_rdev);
993 if (lv_ptr->lv_open == 1) vg_ptr->lv_open--;
994 lv_ptr->lv_open--;
996 MOD_DEC_USE_COUNT;
998 return 0;
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;
1012 static off_t sz;
1013 off_t sz_last;
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 */
1018 vg_t *vg_ptr;
1019 lv_t *lv_ptr;
1020 pv_t *pv_ptr;
1023 #ifdef DEBUG_LVM_PROC_GET_INFO
1024 printk(KERN_DEBUG
1025 "%s - lvm_proc_get_info CALLED pos: %lu count: %d whence: %d\n",
1026 lvm_name, pos, count, whence);
1027 #endif
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) {
1036 vg_counter++;
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) {
1046 lv_open_counter++;
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);
1057 if (buf != NULL) {
1058 #ifdef DEBUG_KFREE
1059 printk(KERN_DEBUG
1060 "%s -- kfree %d\n", lvm_name, __LINE__);
1061 #endif
1062 kfree(buf);
1063 buf = NULL;
1065 /* 2 times: first to get size to allocate buffer,
1066 2nd to fill the malloced buffer */
1067 for (i = 0; i < 2; i++) {
1068 sz = 0;
1069 sz += sprintf(LVM_PROC_BUF,
1070 "LVM "
1071 #ifdef MODULE
1072 "module"
1073 #else
1074 "driver"
1075 #endif
1076 " %s\n\n"
1077 "Total: %d VG%s %d PV%s %d LV%s ",
1078 lvm_short_version,
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,
1083 "(%d LV%s open",
1084 lv_open_counter,
1085 lv_open_counter == 1 ? "" : "s");
1086 if (lv_open_total > 0)
1087 sz += sprintf(LVM_PROC_BUF,
1088 " %d times)\n",
1089 lv_open_total);
1090 else
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,
1098 lvm_iop_version);
1100 seconds = CURRENT_TIME - loadtime;
1101 if (seconds < 0)
1102 loadtime = CURRENT_TIME + seconds;
1103 if (seconds / 86400 > 0) {
1104 sz += sprintf(LVM_PROC_BUF, "%d day%s ",
1105 seconds / 86400,
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,
1112 seconds % 60);
1114 if (vg_counter > 0) {
1115 for (v = 0; v < ABS_MAX_VG; v++) {
1116 /* volume group */
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] "
1122 " PE Size: %d KB\n"
1123 " Usage [KB/PE]: %d /%d total "
1124 "%d /%d used %d /%d free",
1125 inactive_flag,
1126 vg_ptr->vg_name,
1127 vg_ptr->pv_cur,
1128 vg_ptr->lv_cur,
1129 vg_ptr->lv_open,
1130 vg_ptr->pe_size >> 1,
1131 vg_ptr->pe_size * vg_ptr->pe_total >> 1,
1132 vg_ptr->pe_total,
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,
1141 "\n PV%s ",
1142 vg_ptr->pv_cur == 1 ? ": " : "s:");
1143 c = 0;
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;
1154 else pv_name++;
1155 sz += sprintf(LVM_PROC_BUF,
1156 "[%c%c] %-21s %8d /%-6d "
1157 "%8d /%-6d %8d /%-6d",
1158 inactive_flag,
1159 allocation_flag,
1160 pv_name,
1161 pv_ptr->pe_total *
1162 pv_ptr->pe_size >> 1,
1163 pv_ptr->pe_total,
1164 pv_ptr->pe_allocated *
1165 pv_ptr->pe_size >> 1,
1166 pv_ptr->pe_allocated,
1167 (pv_ptr->pe_total -
1168 pv_ptr->pe_allocated) *
1169 pv_ptr->pe_size >> 1,
1170 pv_ptr->pe_total -
1171 pv_ptr->pe_allocated);
1172 c++;
1173 if (c < vg_ptr->pv_cur)
1174 sz += sprintf(LVM_PROC_BUF,
1175 "\n ");
1179 /* logical volumes */
1180 sz += sprintf(LVM_PROC_BUF,
1181 "\n LV%s ",
1182 vg_ptr->lv_cur == 1 ? ": " : "s:");
1183 c = 0;
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';
1189 rw_flag = 'R';
1190 if (lv_ptr->lv_access & LV_WRITE)
1191 rw_flag = 'W';
1192 allocation_flag = 'D';
1193 if (lv_ptr->lv_allocation & LV_CONTIGUOUS)
1194 allocation_flag = 'C';
1195 stripes_flag = 'L';
1196 if (lv_ptr->lv_stripes > 1)
1197 stripes_flag = 'S';
1198 sz += sprintf(LVM_PROC_BUF,
1199 "[%c%c%c%c",
1200 inactive_flag,
1201 rw_flag,
1202 allocation_flag,
1203 stripes_flag);
1204 if (lv_ptr->lv_stripes > 1)
1205 sz += sprintf(LVM_PROC_BUF, "%-2d",
1206 lv_ptr->lv_stripes);
1207 else
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;
1211 else lv_name++;
1212 sz += sprintf(LVM_PROC_BUF, "] %-25s", lv_name);
1213 if (strlen(lv_name) > 25)
1214 sz += sprintf(LVM_PROC_BUF,
1215 "\n ");
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");
1222 else
1223 sz += sprintf(LVM_PROC_BUF, "%dx open",
1224 lv_ptr->lv_open);
1225 c++;
1226 if (c < vg_ptr->lv_cur)
1227 sz += sprintf(LVM_PROC_BUF,
1228 "\n ");
1231 if (vg_ptr->lv_cur == 0) sz += sprintf(LVM_PROC_BUF, "none");
1232 sz += sprintf(LVM_PROC_BUF, "\n");
1236 if (buf == NULL) {
1237 if ((buf = vmalloc(sz)) == NULL) {
1238 sz = 0;
1239 return sprintf(page, "%s - vmalloc error at line %d\n",
1240 lvm_name, __LINE__);
1243 sz_last = sz;
1246 if (pos > sz - 1) {
1247 vfree(buf);
1248 buf = NULL;
1249 return 0;
1251 *start = &buf[pos];
1252 if (sz - pos < count)
1253 return sz - pos;
1254 else
1255 return 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);
1267 ulong index;
1268 ulong pe_start;
1269 ulong size = bh->b_size >> 9;
1270 ulong rsector_tmp = bh->b_rsector;
1271 ulong rsector_sav;
1272 kdev_t rdev_tmp = bh->b_rdev;
1273 kdev_t rdev_sav;
1274 lv_t *lv = vg[VG_BLK(minor)]->lv[LV_BLK(minor)];
1277 if (!(lv->lv_status & LV_ACTIVE)) {
1278 printk(KERN_ALERT
1279 "%s - lvm_map: ll_rw_blk for inactive LV %s\n",
1280 lvm_name, lv->lv_name);
1281 goto error;
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);
1296 goto error;
1299 if ((rw == WRITE || rw == WRITEA) &&
1300 !(lv->lv_access & LV_WRITE)) {
1301 printk(KERN_CRIT
1302 "%s - lvm_map: ll_rw_blk write for readonly LV %s\n",
1303 lvm_name, lv->lv_name);
1304 goto error;
1306 #ifdef DEBUG_MAP
1307 printk(KERN_DEBUG
1308 "%s - lvm_map minor:%d *rdev: %02d:%02d *rsector: %lu "
1309 "size:%lu\n",
1310 lvm_name, minor,
1311 MAJOR(rdev_tmp),
1312 MINOR(rdev_tmp),
1313 rsector_tmp, size);
1314 #endif
1316 if (rsector_tmp + size > lv->lv_size) {
1317 printk(KERN_ALERT
1318 "%s - lvm_map *rsector: %lu or size: %lu wrong for"
1319 " minor: %2d\n", lvm_name, rsector_tmp, size, minor);
1320 goto error;
1322 rsector_sav = rsector_tmp;
1323 rdev_sav = rdev_tmp;
1325 lvm_second_remap:
1326 /* linear mapping */
1327 if (lv->lv_stripes < 2) {
1328 /* get the index */
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;
1335 #ifdef DEBUG_MAP
1336 printk(KERN_DEBUG
1337 "lv_current_pe[%ld].pe: %ld rdev: %02d:%02d rsector:%ld\n",
1338 index,
1339 lv->lv_current_pe[index].pe,
1340 MAJOR(rdev_tmp),
1341 MINOR(rdev_tmp),
1342 rsector_tmp);
1343 #endif
1345 /* striped mapping */
1346 } else {
1347 ulong stripe_index;
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;
1364 #ifdef DEBUG_MAP
1365 printk(KERN_DEBUG
1366 "lv_current_pe[%ld].pe: %ld rdev: %02d:%02d rsector:%ld\n"
1367 "stripe_length: %ld stripe_index: %ld\n",
1368 index,
1369 lv->lv_current_pe[index].pe,
1370 MAJOR(rdev_tmp),
1371 MINOR(rdev_tmp),
1372 rsector_tmp,
1373 stripe_length,
1374 stripe_index);
1375 #endif
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;
1389 /* statistic */
1390 if (rw == WRITE || rw == WRITEA)
1391 lv->lv_current_pe[index].writes++;
1392 else
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)
1401 lv_t *lv_ptr;
1403 /* start with first snapshot and loop thrugh all of them */
1404 for (lv_ptr = lv->lv_snapshot_next;
1405 lv_ptr != NULL;
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,
1413 &rsector_tmp,
1414 pe_start,
1415 lv_ptr)) {
1416 /* create a new mapping */
1417 lvm_snapshot_COW(rdev_tmp,
1418 rsector_tmp,
1419 pe_start,
1420 rsector_sav,
1421 lv_ptr);
1423 rdev_tmp = rdev_sav;
1424 rsector_tmp = rsector_sav;
1426 up(&lv->lv_snapshot_org->lv_snapshot_sem);
1429 } else {
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;
1440 return 1;
1442 error:
1443 buffer_IO_error(bh);
1444 return -1;
1445 } /* lvm_map() */
1449 * internal support functions
1452 #ifdef LVM_HD_NAME
1454 * generate "hard disk" name
1456 void lvm_hd_name(char *buf, int minor)
1458 int len = 0;
1459 lv_t *lv_ptr;
1461 if (vg[VG_BLK(minor)] == NULL ||
1462 (lv_ptr = vg[VG_BLK(minor)]->lv[LV_BLK(minor)]) == NULL)
1463 return;
1464 len = strlen(lv_ptr->lv_name) - 5;
1465 memcpy(buf, &lv_ptr->lv_name[5], len);
1466 buf[len] = 0;
1467 return;
1469 #endif
1473 * this one never should be called...
1475 static void lvm_dummy_device_request(request_queue_t * t)
1477 printk(KERN_EMERG
1478 "%s -- oops, got lvm request for %02d:%02d [sector: %lu]\n",
1479 lvm_name,
1480 MAJOR(CURRENT->rq_dev),
1481 MINOR(CURRENT->rq_dev),
1482 CURRENT->sector);
1483 return;
1488 * make request function
1490 static int lvm_make_request_fn(request_queue_t *q, int rw, struct buffer_head *bh)
1492 lvm_map(bh, rw);
1493 return 1;
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)
1513 lock_try_again:
1514 spin_lock(&lvm_lock);
1515 if (lock != 0 && lock != current->pid) {
1516 #ifdef DEBUG_IOCTL
1517 printk(KERN_INFO "lvm_do_lock_lvm: %s is locked by pid %d ...\n",
1518 lvm_name, lock);
1519 #endif
1520 spin_unlock(&lvm_lock);
1521 interruptible_sleep_on(&lvm_wait);
1522 if (current->sigpending != 0)
1523 return -EINTR;
1524 #ifdef LVM_TOTAL_RESET
1525 if (lvm_reset_spindown > 0)
1526 return -EACCES;
1527 #endif
1528 goto lock_try_again;
1530 lock = current->pid;
1531 spin_unlock(&lvm_lock);
1532 return 0;
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)
1541 uint p;
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) {
1548 case LOCK_PE:
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)
1553 break;
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;
1560 break;
1562 case UNLOCK_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);
1568 break;
1570 default:
1571 return -EINVAL;
1573 return 0;
1578 * character device support function logical extend remap
1580 static int lvm_do_le_remap(vg_t *vg_ptr, void *arg)
1582 uint l, le;
1583 lv_t *lv_ptr;
1585 if (vg_ptr == NULL) return -ENXIO;
1586 if (copy_from_user(&le_remap_req, arg,
1587 sizeof(le_remap_req_t)) != 0)
1588 return -EFAULT;
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;
1596 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;
1605 return 0;
1608 return -EINVAL;
1611 return -ENXIO;
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;
1621 ulong l, p;
1622 lv_t lv;
1623 vg_t *vg_ptr;
1624 pv_t *pv_ptr;
1625 lv_t *lv_ptr;
1627 if (vg[VG_CHR(minor)] != NULL) return -EPERM;
1629 if ((vg_ptr = kmalloc(sizeof(vg_t),GFP_KERNEL)) == NULL) {
1630 printk(KERN_CRIT
1631 "%s -- VG_CREATE: kmalloc error VG at line %d\n",
1632 lvm_name, __LINE__);
1633 return -ENOMEM;
1635 /* get the volume group structure */
1636 if (copy_from_user(vg_ptr, arg, sizeof(vg_t)) != 0) {
1637 kfree(vg_ptr);
1638 return -EFAULT;
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) {
1654 printk(KERN_WARNING
1655 "%s -- Can't activate VG: ABS_MAX_PV too small\n",
1656 lvm_name);
1657 kfree(vg_ptr);
1658 vg[VG_CHR(minor)] = NULL;
1659 return -EPERM;
1661 if (vg_ptr->lv_max > ABS_MAX_LV) {
1662 printk(KERN_WARNING
1663 "%s -- Can't activate VG: ABS_MAX_LV too small for %u\n",
1664 lvm_name, vg_ptr->lv_max);
1665 kfree(vg_ptr);
1666 vg_ptr = NULL;
1667 return -EPERM;
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) {
1676 printk(KERN_CRIT
1677 "%s -- VG_CREATE: kmalloc error PV at line %d\n",
1678 lvm_name, __LINE__);
1679 lvm_do_vg_remove(minor);
1680 return -ENOMEM;
1682 if (copy_from_user(pv_ptr, pvp, sizeof(pv_t)) != 0) {
1683 lvm_do_vg_remove(minor);
1684 return -EFAULT;
1686 /* We don't need the PE list
1687 in kernel space as with LVs pe_t list (see below) */
1688 pv_ptr->pe = NULL;
1689 pv_ptr->pe_allocated = 0;
1690 pv_ptr->pv_status = PV_ACTIVE;
1691 vg_ptr->pv_act++;
1692 vg_ptr->pv_cur++;
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);
1697 #endif
1701 /* get the logical volume structures */
1702 vg_ptr->lv_cur = 0;
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);
1708 return -EFAULT;
1710 vg_ptr->lv[l] = NULL;
1711 if (lvm_do_lv_create(minor, lv.lv_name, &lv) != 0) {
1712 lvm_do_vg_remove(minor);
1713 return -EFAULT;
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;
1756 lv_ptr->lv_size =
1757 vg_ptr->lv[LV_BLK(snaporg_minor)]->lv_size;
1762 vg_count++;
1764 /* let's go active */
1765 vg_ptr->vg_status |= VG_ACTIVE;
1767 MOD_INC_USE_COUNT;
1769 return 0;
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)
1778 uint p;
1779 pv_t *pv_ptr;
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) {
1786 printk(KERN_CRIT
1787 "%s -- VG_EXTEND: kmalloc error PV at line %d\n",
1788 lvm_name, __LINE__);
1789 return -ENOMEM;
1791 if (copy_from_user(pv_ptr, arg, sizeof(pv_t)) != 0) {
1792 kfree(pv_ptr);
1793 vg_ptr->pv[p] = NULL;
1794 return -EFAULT;
1797 pv_ptr->pv_status = PV_ACTIVE;
1798 /* We don't need the PE list
1799 in kernel space like LVs pe_t list */
1800 pv_ptr->pe = NULL;
1801 vg_ptr->pv_cur++;
1802 vg_ptr->pv_act++;
1803 vg_ptr->pe_total +=
1804 pv_ptr->pe_total;
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);
1808 #endif
1809 return 0;
1813 return -EPERM;
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)
1822 uint p;
1823 pv_t *pv_ptr;
1825 if (vg_ptr == NULL) return -ENXIO;
1826 if (copy_from_user(pv_name, arg, sizeof(pv_name)) != 0)
1827 return -EFAULT;
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,
1833 pv_name) == 0) {
1834 if (pv_ptr->lv_cur > 0) return -EPERM;
1835 vg_ptr->pe_total -=
1836 pv_ptr->pe_total;
1837 vg_ptr->pv_cur--;
1838 vg_ptr->pv_act--;
1839 #ifdef LVM_GET_INODE
1840 lvm_clear_inode(pv_ptr->inode);
1841 #endif
1842 kfree(pv_ptr);
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;
1847 return 0;
1850 return -ENXIO;
1851 } /* lvm_do_vg_reduce */
1855 * character device support function VGDA remove
1857 static int lvm_do_vg_remove(int minor)
1859 int i;
1860 vg_t *vg_ptr = vg[VG_CHR(minor)];
1861 pv_t *pv_ptr;
1863 if (vg_ptr == NULL) return -ENXIO;
1865 #ifdef LVM_TOTAL_RESET
1866 if (vg_ptr->lv_open > 0 && lvm_reset_spindown == 0)
1867 #else
1868 if (vg_ptr->lv_open > 0)
1869 #endif
1870 return -EPERM;
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]);
1878 /* free LVs */
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);
1897 /* free PVs */
1898 for (i = 0; i < vg_ptr->pv_max; i++) {
1899 if ((pv_ptr = vg_ptr->pv[i]) != NULL) {
1900 #ifdef DEBUG_KFREE
1901 printk(KERN_DEBUG
1902 "%s -- kfree %d\n", lvm_name, __LINE__);
1903 #endif
1904 #ifdef LVM_GET_INODE
1905 lvm_clear_inode(pv_ptr->inode);
1906 #endif
1907 kfree(pv_ptr);
1908 vg[VG_CHR(minor)]->pv[i] = NULL;
1912 #ifdef DEBUG_KFREE
1913 printk(KERN_DEBUG "%s -- kfree %d\n", lvm_name, __LINE__);
1914 #endif
1915 kfree(vg_ptr);
1916 vg[VG_CHR(minor)] = NULL;
1918 vg_count--;
1920 MOD_DEC_USE_COUNT;
1922 return 0;
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)
1940 return -EINVAL;
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)
1945 return -EEXIST;
1948 /* in case of lv_remove(), lv_create() pair; for eg. lvrename does this */
1949 l_new = -1;
1950 if (vg_ptr->lv[lv->lv_number] == NULL)
1951 l_new = lv->lv_number;
1952 else {
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;
1959 else l = l_new;
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__);
1964 return -ENOMEM;
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) {
1983 printk(KERN_CRIT
1984 "%s -- LV_CREATE: vmalloc error LV_CURRENT_PE of %d Byte "
1985 "at line %d\n",
1986 lvm_name, size, __LINE__);
1987 #ifdef DEBUG_KFREE
1988 printk(KERN_DEBUG "%s -- kfree %d\n", lvm_name, __LINE__);
1989 #endif
1990 kfree(lv_ptr);
1991 vg[VG_CHR(minor)]->lv[l] = NULL;
1992 return -ENOMEM;
1994 if (copy_from_user(lv_ptr->lv_current_pe, pep, size)) {
1995 vfree(lv_ptr->lv_current_pe);
1996 kfree(lv_ptr);
1997 vg_ptr->lv[l] = NULL;
1998 return -EFAULT;
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++;
2009 } else {
2010 /* Get snapshot exception data and block list */
2011 if (lvbe != NULL) {
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) {
2017 printk(KERN_CRIT
2018 "%s -- lvm_do_lv_create: vmalloc error LV_BLOCK_EXCEPTION "
2019 "of %d byte at line %d\n",
2020 lvm_name, size, __LINE__);
2021 #ifdef DEBUG_KFREE
2022 printk(KERN_DEBUG "%s -- kfree %d\n", lvm_name, __LINE__);
2023 #endif
2024 kfree(lv_ptr);
2025 vg_ptr->lv[l] = NULL;
2026 return -ENOMEM;
2028 if (copy_from_user(lv_ptr->lv_block_exception, lvbe, size)) {
2029 vfree(lv_ptr->lv_block_exception);
2030 kfree(lv_ptr);
2031 vg[VG_CHR(minor)]->lv[l] = NULL;
2032 return -EFAULT;
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);
2058 if (err)
2060 vfree(lv_ptr->lv_block_exception);
2061 kfree(lv_ptr);
2062 vg[VG_CHR(minor)]->lv[l] = NULL;
2063 return err;
2066 } else {
2067 vfree(lv_ptr->lv_block_exception);
2068 kfree(lv_ptr);
2069 vg_ptr->lv[l] = NULL;
2070 return -EFAULT;
2072 } else {
2073 kfree(vg_ptr->lv[l]);
2074 vg_ptr->lv[l] = NULL;
2075 return -EINVAL;
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);
2086 vg_ptr->lv_cur++;
2087 lv_ptr->lv_status = lv_status_save;
2089 strtok(lv->lv_name, "/"); /* /dev */
2091 while((lv_tmp = strtok(NULL, "/")) != NULL)
2092 lv_buf = lv_tmp;
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;
2108 return 0;
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)
2117 uint le, p;
2118 vg_t *vg_ptr = vg[VG_CHR(minor)];
2119 lv_t *lv_ptr;
2121 if (l == -1) {
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) {
2125 break;
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)
2134 #else
2135 if (lv_ptr->lv_open > 0)
2136 #endif
2137 return -EBUSY;
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)
2143 return -EPERM;
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);
2178 /* LV_SNAPSHOT */
2179 } else {
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]);
2194 #ifdef DEBUG_KFREE
2195 printk(KERN_DEBUG "%s -- kfree %d\n", lvm_name, __LINE__);
2196 #endif
2197 kfree(lv_ptr);
2198 vg_ptr->lv[l] = NULL;
2199 vg_ptr->lv_cur--;
2200 return 0;
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)];
2212 lv_t *lv_ptr;
2213 pe_t *pe;
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)
2220 break;
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) {
2229 printk(KERN_CRIT
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__);
2233 return -ENOMEM;
2235 /* get the PE structures from user space */
2236 if (copy_from_user(pe, pep, size)) {
2237 vfree(pe);
2238 return -EFAULT;
2241 #ifdef DEBUG
2242 printk(KERN_DEBUG
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),
2247 vg_ptr->vg_name);
2248 #endif
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--;
2262 break;
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 */
2296 } else {
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;
2315 vfree(pep1);
2316 pep1 = NULL;
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++;
2326 break;
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;
2339 return 0;
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)
2348 uint l;
2349 ulong size;
2350 lv_t lv;
2351 lv_t *lv_ptr;
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)
2357 return -EFAULT;
2359 if (lv_status_byname_req.lv == NULL) return -EINVAL;
2360 if (copy_from_user(&lv, lv_status_byname_req.lv,
2361 sizeof(lv_t)) != 0)
2362 return -EFAULT;
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,
2370 lv_ptr,
2371 sizeof(lv_t)) != 0)
2372 return -EFAULT;
2374 if (lv.lv_current_pe != NULL) {
2375 size = lv_ptr->lv_allocated_le *
2376 sizeof(pe_t);
2377 if (copy_to_user(lv.lv_current_pe,
2378 lv_ptr->lv_current_pe,
2379 size) != 0)
2380 return -EFAULT;
2382 return 0;
2385 return -ENXIO;
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)
2394 ulong size;
2395 lv_t lv;
2396 lv_t *lv_ptr;
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)
2402 return -EFAULT;
2404 if ((lvp = lv_status_byindex_req.lv) == NULL)
2405 return -EINVAL;
2406 if ( ( lv_ptr = vg_ptr->lv[lv_status_byindex_req.lv_index]) == NULL)
2407 return -ENXIO;
2409 if (copy_from_user(&lv, lvp, sizeof(lv_t)) != 0)
2410 return -EFAULT;
2412 if (copy_to_user(lvp, lv_ptr, sizeof(lv_t)) != 0)
2413 return -EFAULT;
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,
2419 size) != 0)
2420 return -EFAULT;
2422 return 0;
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)
2431 uint p;
2432 pv_t *pv_ptr;
2433 #ifdef LVM_GET_INODE
2434 struct inode *inode_sav;
2435 #endif
2437 if (vg_ptr == NULL) return -ENXIO;
2438 if (copy_from_user(&pv_change_req, arg,
2439 sizeof(pv_change_req)) != 0)
2440 return -EFAULT;
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;
2449 #endif
2450 if (copy_from_user(pv_ptr,
2451 pv_change_req.pv,
2452 sizeof(pv_t)) != 0)
2453 return -EFAULT;
2455 /* We don't need the PE list
2456 in kernel space as with LVs pe_t list */
2457 pv_ptr->pe = NULL;
2458 #ifdef LVM_GET_INODE
2459 pv_ptr->inode = inode_sav;
2460 #endif
2461 return 0;
2464 return -ENXIO;
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)
2472 uint p;
2473 pv_t *pv_ptr;
2475 if (vg_ptr == NULL) return -ENXIO;
2476 if (copy_from_user(&pv_status_req, arg,
2477 sizeof(pv_status_req)) != 0)
2478 return -EFAULT;
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,
2486 pv_ptr,
2487 sizeof(pv_t)) != 0)
2488 return -EFAULT;
2489 return 0;
2492 return -ENXIO;
2493 } /* lvm_do_pv_status() */
2497 * support function initialize gendisk variables
2499 #ifdef __initfunc
2500 __initfunc(void lvm_geninit(struct gendisk *lvm_gdisk))
2501 #else
2502 void __init
2503 lvm_geninit(struct gendisk *lvm_gdisk)
2504 #endif
2506 int i = 0;
2508 #ifdef DEBUG_GENDISK
2509 printk(KERN_DEBUG "%s -- lvm_gendisk\n", lvm_name);
2510 #endif
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;
2521 return;
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);
2553 return inode_this;
2558 * support function to clear an inode
2561 void lvm_clear_inode(struct inode *inode)
2563 #ifdef I_FREEING
2564 inode->i_state |= I_FREEING;
2565 #endif
2566 clear_inode(inode);
2567 return;
2569 #endif /* #ifdef LVM_GET_INODE */