1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80#ifndef _LVM_H_INCLUDE
81#define _LVM_H_INCLUDE
82
83#define LVM_RELEASE_NAME "1.0.8"
84#define LVM_RELEASE_DATE "17/11/2003"
85
86#define _LVM_KERNEL_H_VERSION "LVM "LVM_RELEASE_NAME" ("LVM_RELEASE_DATE")"
87
88#include <linux/version.h>
89
90
91
92
93
94#define LVM_TOTAL_RESET
95
96#ifdef __KERNEL__
97#undef LVM_HD_NAME
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112#include <linux/kdev_t.h>
113#include <linux/list.h>
114#include <asm/types.h>
115#include <linux/major.h>
116#else
117
118
119
120struct list_head {
121 struct list_head *next, *prev;
122};
123#define __KERNEL__
124#include <linux/kdev_t.h>
125#undef __KERNEL__
126#endif
127
128
129#ifdef __KERNEL__
130#include <linux/spinlock.h>
131
132#include <asm/semaphore.h>
133#endif
134
135
136#include <asm/page.h>
137
138#if !defined ( LVM_BLK_MAJOR) || !defined ( LVM_CHAR_MAJOR)
139#error Bad include/linux/major.h - LVM MAJOR undefined
140#endif
141
142#ifdef BLOCK_SIZE
143#undef BLOCK_SIZE
144#endif
145
146#ifdef CONFIG_ARCH_S390
147#define BLOCK_SIZE 4096
148#else
149#define BLOCK_SIZE 1024
150#endif
151
152#ifndef SECTOR_SIZE
153#define SECTOR_SIZE 512
154#endif
155
156
157#define LVM_STRUCT_VERSION 1
158
159#define LVM_DIR_PREFIX "/dev/"
160
161
162
163
164
165
166
167
168#define LVM_DRIVER_IOP_VERSION 10
169
170#define LVM_NAME "lvm"
171#define LVM_GLOBAL "global"
172#define LVM_DIR "lvm"
173#define LVM_VG_SUBDIR "VGs"
174#define LVM_LV_SUBDIR "LVs"
175#define LVM_PV_SUBDIR "PVs"
176
177
178
179
180
181#define VG_CHR(a) ( a)
182
183
184#define VG_BLK(a) ( vg_lv_map[a].vg_number)
185#define LV_BLK(a) ( vg_lv_map[a].lv_number)
186
187
188
189
190#define ABS_MAX_VG 99
191#define ABS_MAX_PV 256
192#define ABS_MAX_LV 256
193
194#define MAX_VG ABS_MAX_VG
195#define MAX_LV ABS_MAX_LV
196#define MAX_PV ABS_MAX_PV
197
198#if ( MAX_VG > ABS_MAX_VG)
199#undef MAX_VG
200#define MAX_VG ABS_MAX_VG
201#endif
202
203#if ( MAX_LV > ABS_MAX_LV)
204#undef MAX_LV
205#define MAX_LV ABS_MAX_LV
206#endif
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258#define LVM_PE_T_MAX ( ( 1 << ( sizeof ( uint16_t) * 8)) - 2)
259
260#define LVM_LV_SIZE_MAX(a) ( ( long long) LVM_PE_T_MAX * (a)->pe_size > ( long long) 1024*1024/SECTOR_SIZE*1024*1024 ? ( long long) 1024*1024/SECTOR_SIZE*1024*1024 : ( long long) LVM_PE_T_MAX * (a)->pe_size)
261#define LVM_MIN_PE_SIZE ( 8192L / SECTOR_SIZE)
262#define LVM_MAX_PE_SIZE ( 16L * 1024L * 1024L / SECTOR_SIZE * 1024)
263#define LVM_DEFAULT_PE_SIZE ( 32768L * 1024 / SECTOR_SIZE)
264#define LVM_DEFAULT_STRIPE_SIZE 16L
265#define LVM_MIN_STRIPE_SIZE ( PAGE_SIZE/SECTOR_SIZE)
266#define LVM_MAX_STRIPE_SIZE ( 512L * 1024 / SECTOR_SIZE)
267#define LVM_MAX_STRIPES 128
268#define LVM_MAX_SIZE ( 1024LU * 1024 / SECTOR_SIZE * 1024 * 1024)
269#define LVM_MAX_MIRRORS 2
270#define LVM_MIN_READ_AHEAD 0
271#define LVM_DEFAULT_READ_AHEAD 1024
272#define LVM_MAX_READ_AHEAD 1024
273#define LVM_MAX_LV_IO_TIMEOUT 60
274#define LVM_PARTITION 0xfe
275#define LVM_NEW_PARTITION 0x8e
276#define LVM_PE_SIZE_PV_SIZE_REL 5
277
278#define LVM_SNAPSHOT_MAX_CHUNK 1024
279#define LVM_SNAPSHOT_DEF_CHUNK 64
280#define LVM_SNAPSHOT_MIN_CHUNK (PAGE_SIZE/1024)
281
282#define UNDEF -1
283
284
285
286
287
288
289
290
291#define VG_CREATE_OLD _IOW ( 0xfe, 0x00, 1)
292#define VG_REMOVE _IOW ( 0xfe, 0x01, 1)
293
294#define VG_EXTEND _IOW ( 0xfe, 0x03, 1)
295#define VG_REDUCE _IOW ( 0xfe, 0x04, 1)
296
297#define VG_STATUS _IOWR ( 0xfe, 0x05, 1)
298#define VG_STATUS_GET_COUNT _IOWR ( 0xfe, 0x06, 1)
299#define VG_STATUS_GET_NAMELIST _IOWR ( 0xfe, 0x07, 1)
300
301#define VG_SET_EXTENDABLE _IOW ( 0xfe, 0x08, 1)
302#define VG_RENAME _IOW ( 0xfe, 0x09, 1)
303
304
305#define VG_CREATE _IOW ( 0xfe, 0x0a, 1)
306
307
308#define LV_CREATE _IOW ( 0xfe, 0x20, 1)
309#define LV_REMOVE _IOW ( 0xfe, 0x21, 1)
310
311#define LV_ACTIVATE _IO ( 0xfe, 0x22)
312#define LV_DEACTIVATE _IO ( 0xfe, 0x23)
313
314#define LV_EXTEND _IOW ( 0xfe, 0x24, 1)
315#define LV_REDUCE _IOW ( 0xfe, 0x25, 1)
316
317#define LV_STATUS_BYNAME _IOWR ( 0xfe, 0x26, 1)
318#define LV_STATUS_BYINDEX _IOWR ( 0xfe, 0x27, 1)
319
320#define LV_SET_ACCESS _IOW ( 0xfe, 0x28, 1)
321#define LV_SET_ALLOCATION _IOW ( 0xfe, 0x29, 1)
322#define LV_SET_STATUS _IOW ( 0xfe, 0x2a, 1)
323
324#define LE_REMAP _IOW ( 0xfe, 0x2b, 1)
325
326#define LV_SNAPSHOT_USE_RATE _IOWR ( 0xfe, 0x2c, 1)
327
328#define LV_STATUS_BYDEV _IOWR ( 0xfe, 0x2e, 1)
329
330#define LV_RENAME _IOW ( 0xfe, 0x2f, 1)
331
332#define LV_BMAP _IOWR ( 0xfe, 0x30, 1)
333
334
335
336#define PV_STATUS _IOWR ( 0xfe, 0x40, 1)
337#define PV_CHANGE _IOWR ( 0xfe, 0x41, 1)
338#define PV_FLUSH _IOW ( 0xfe, 0x42, 1)
339
340
341#define PE_LOCK_UNLOCK _IOW ( 0xfe, 0x50, 1)
342
343
344#define LVM_GET_IOP_VERSION _IOR ( 0xfe, 0x98, 1)
345
346#ifdef LVM_TOTAL_RESET
347
348#define LVM_RESET _IO ( 0xfe, 0x99)
349#endif
350
351
352#if LVM_DRIVER_IOP_VERSION > 11
353#define LVM_LOCK_LVM _IO ( 0xfe, 0x9A)
354#else
355
356#define LVM_LOCK_LVM _IO ( 0xfe, 0x100)
357#endif
358
359
360
361
362
363
364
365#define VG_ACTIVE 0x01
366#define VG_EXPORTED 0x02
367#define VG_EXTENDABLE 0x04
368
369#define VG_READ 0x01
370#define VG_WRITE 0x02
371#define VG_CLUSTERED 0x04
372#define VG_SHARED 0x08
373
374
375#define LV_ACTIVE 0x01
376#define LV_SPINDOWN 0x02
377
378#define LV_READ 0x01
379#define LV_WRITE 0x02
380#define LV_SNAPSHOT 0x04
381#define LV_SNAPSHOT_ORG 0x08
382
383#define LV_BADBLOCK_ON 0x01
384
385#define LV_STRICT 0x01
386#define LV_CONTIGUOUS 0x02
387
388
389#define PV_ACTIVE 0x01
390#define PV_ALLOCATABLE 0x02
391
392
393
394#define LVM_SNAPSHOT_DROPPED_SECTOR 1
395
396
397
398
399
400
401
402
403
404#define NAME_LEN 128
405#define UUID_LEN 32
406
407
408typedef struct lv_COW_table_disk_v1 {
409 uint64_t pv_org_number;
410 uint64_t pv_org_rsector;
411 uint64_t pv_snap_number;
412 uint64_t pv_snap_rsector;
413} lv_COW_table_disk_t;
414
415
416typedef struct lv_block_exception_v1 {
417 struct list_head hash;
418 uint32_t rsector_org;
419 kdev_t rdev_org;
420 uint32_t rsector_new;
421 kdev_t rdev_new;
422} lv_block_exception_t;
423
424
425typedef struct {
426 uint16_t lv_num;
427 uint16_t le_num;
428} pe_disk_t;
429
430
431typedef struct {
432 uint32_t base;
433 uint32_t size;
434} lvm_disk_data_t;
435
436
437
438
439
440
441
442typedef struct pv_v2 {
443 char id[2];
444 unsigned short version;
445 lvm_disk_data_t pv_on_disk;
446 lvm_disk_data_t vg_on_disk;
447 lvm_disk_data_t pv_uuidlist_on_disk;
448 lvm_disk_data_t lv_on_disk;
449 lvm_disk_data_t pe_on_disk;
450 char pv_name[NAME_LEN];
451 char vg_name[NAME_LEN];
452 char system_id[NAME_LEN];
453 kdev_t pv_dev;
454 uint pv_number;
455 uint pv_status;
456 uint pv_allocatable;
457 uint pv_size;
458 uint lv_cur;
459 uint pe_size;
460 uint pe_total;
461 uint pe_allocated;
462 uint pe_stale;
463 pe_disk_t *pe;
464 struct block_device *bd;
465 char pv_uuid[UUID_LEN + 1];
466
467#ifndef __KERNEL__
468 uint32_t pe_start;
469#endif
470} pv_t;
471
472
473
474typedef struct pv_disk_v2 {
475 uint8_t id[2];
476 uint16_t version;
477 lvm_disk_data_t pv_on_disk;
478 lvm_disk_data_t vg_on_disk;
479 lvm_disk_data_t pv_uuidlist_on_disk;
480 lvm_disk_data_t lv_on_disk;
481 lvm_disk_data_t pe_on_disk;
482 uint8_t pv_uuid[NAME_LEN];
483 uint8_t vg_name[NAME_LEN];
484 uint8_t system_id[NAME_LEN];
485 uint32_t pv_major;
486 uint32_t pv_number;
487 uint32_t pv_status;
488 uint32_t pv_allocatable;
489 uint32_t pv_size;
490 uint32_t lv_cur;
491 uint32_t pe_size;
492 uint32_t pe_total;
493 uint32_t pe_allocated;
494
495
496 uint32_t pe_start;
497
498} pv_disk_t;
499
500
501
502
503
504
505
506typedef struct {
507 kdev_t dev;
508 uint32_t pe;
509 uint32_t reads;
510 uint32_t writes;
511} pe_t;
512
513typedef struct {
514 char lv_name[NAME_LEN];
515 kdev_t old_dev;
516 kdev_t new_dev;
517 uint32_t old_pe;
518 uint32_t new_pe;
519} le_remap_req_t;
520
521typedef struct lv_bmap {
522 uint32_t lv_block;
523 dev_t lv_dev;
524} lv_bmap_t;
525
526
527
528
529
530
531typedef struct lv_v5 {
532 char lv_name[NAME_LEN];
533 char vg_name[NAME_LEN];
534 uint lv_access;
535 uint lv_status;
536 uint lv_open;
537 kdev_t lv_dev;
538 uint lv_number;
539 uint lv_mirror_copies;
540 uint lv_recovery;
541 uint lv_schedule;
542 uint lv_size;
543 pe_t *lv_current_pe;
544 uint lv_current_le;
545 uint lv_allocated_le;
546 uint lv_stripes;
547 uint lv_stripesize;
548 uint lv_badblock;
549 uint lv_allocation;
550 uint lv_io_timeout;
551 uint lv_read_ahead;
552
553
554 struct lv_v5 *lv_snapshot_org;
555 struct lv_v5 *lv_snapshot_prev;
556 struct lv_v5 *lv_snapshot_next;
557 lv_block_exception_t *lv_block_exception;
558 uint lv_remap_ptr;
559 uint lv_remap_end;
560 uint lv_chunk_size;
561 uint lv_snapshot_minor;
562#ifdef __KERNEL__
563 struct kiobuf *lv_iobuf;
564 struct kiobuf *lv_COW_table_iobuf;
565 struct rw_semaphore lv_lock;
566 struct list_head *lv_snapshot_hash_table;
567 uint32_t lv_snapshot_hash_table_size;
568 uint32_t lv_snapshot_hash_mask;
569 wait_queue_head_t lv_snapshot_wait;
570 int lv_snapshot_use_rate;
571 struct vg_v3 *vg;
572
573 uint lv_allocated_snapshot_le;
574#else
575 char dummy[200];
576#endif
577} lv_t;
578
579
580typedef struct lv_disk_v3 {
581 uint8_t lv_name[NAME_LEN];
582 uint8_t vg_name[NAME_LEN];
583 uint32_t lv_access;
584 uint32_t lv_status;
585 uint32_t lv_open;
586 uint32_t lv_dev;
587 uint32_t lv_number;
588 uint32_t lv_mirror_copies;
589 uint32_t lv_recovery;
590 uint32_t lv_schedule;
591 uint32_t lv_size;
592 uint32_t lv_snapshot_minor;
593 uint16_t lv_chunk_size;
594 uint16_t dummy;
595 uint32_t lv_allocated_le;
596 uint32_t lv_stripes;
597 uint32_t lv_stripesize;
598 uint32_t lv_badblock;
599 uint32_t lv_allocation;
600 uint32_t lv_io_timeout;
601 uint32_t lv_read_ahead;
602} lv_disk_t;
603
604
605
606
607
608
609typedef struct vg_v3 {
610 char vg_name[NAME_LEN];
611 uint vg_number;
612 uint vg_access;
613 uint vg_status;
614 uint lv_max;
615 uint lv_cur;
616 uint lv_open;
617 uint pv_max;
618 uint pv_cur;
619 uint pv_act;
620 uint dummy;
621 uint vgda;
622 uint pe_size;
623 uint pe_total;
624 uint pe_allocated;
625 uint pvg_total;
626 struct proc_dir_entry *proc;
627 pv_t *pv[ABS_MAX_PV + 1];
628 lv_t *lv[ABS_MAX_LV + 1];
629 char vg_uuid[UUID_LEN + 1];
630#ifdef __KERNEL__
631 struct proc_dir_entry *vg_dir_pde;
632 struct proc_dir_entry *lv_subdir_pde;
633 struct proc_dir_entry *pv_subdir_pde;
634#else
635 char dummy1[200];
636#endif
637} vg_t;
638
639
640
641typedef struct vg_disk_v2 {
642 uint8_t vg_uuid[UUID_LEN];
643 uint8_t vg_name_dummy[NAME_LEN - UUID_LEN];
644 uint32_t vg_number;
645 uint32_t vg_access;
646 uint32_t vg_status;
647 uint32_t lv_max;
648 uint32_t lv_cur;
649 uint32_t lv_open;
650 uint32_t pv_max;
651 uint32_t pv_cur;
652 uint32_t pv_act;
653 uint32_t dummy;
654 uint32_t vgda;
655 uint32_t pe_size;
656 uint32_t pe_total;
657 uint32_t pe_allocated;
658 uint32_t pvg_total;
659} vg_disk_t;
660
661
662
663
664
665
666
667typedef struct {
668 char pv_name[NAME_LEN];
669 pv_t *pv;
670} pv_status_req_t, pv_change_req_t;
671
672
673typedef struct {
674 char pv_name[NAME_LEN];
675 kdev_t pv_dev;
676} pv_flush_req_t;
677
678
679
680typedef struct {
681 enum {
682 LOCK_PE, UNLOCK_PE
683 } lock;
684 struct {
685 kdev_t lv_dev;
686 kdev_t pv_dev;
687 uint32_t pv_offset;
688 } data;
689} pe_lock_req_t;
690
691
692
693typedef struct {
694 char lv_name[NAME_LEN];
695 lv_t *lv;
696} lv_status_byname_req_t, lv_req_t;
697
698
699typedef struct {
700 uint32_t lv_index;
701 lv_t *lv;
702
703 ushort size;
704} lv_status_byindex_req_t;
705
706
707typedef struct {
708 dev_t dev;
709 lv_t *lv;
710} lv_status_bydev_req_t;
711
712
713
714typedef struct {
715 int block;
716 int rate;
717} lv_snapshot_use_rate_req_t;
718
719
720
721
722static inline ulong round_up(ulong n, ulong size)
723{
724 size--;
725 return (n + size) & ~size;
726}
727
728static inline ulong div_up(ulong n, ulong size)
729{
730 return round_up(n, size) / size;
731}
732
733
734static int inline LVM_GET_COW_TABLE_CHUNKS_PER_PE(vg_t * vg, lv_t * lv)
735{
736 return vg->pe_size / lv->lv_chunk_size;
737}
738
739static int inline LVM_GET_COW_TABLE_ENTRIES_PER_PE(vg_t * vg, lv_t * lv)
740{
741 ulong chunks = vg->pe_size / lv->lv_chunk_size;
742 ulong entry_size = sizeof(lv_COW_table_disk_t);
743 ulong chunk_size = lv->lv_chunk_size * SECTOR_SIZE;
744 ulong entries = (vg->pe_size * SECTOR_SIZE) /
745 (entry_size + chunk_size);
746
747 if (chunks < 2)
748 return 0;
749
750 for (; entries; entries--)
751 if ((div_up(entries * entry_size, chunk_size) + entries) <=
752 chunks)
753 break;
754
755 return entries;
756}
757
758
759#endif
760