4 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
7 * This file is part of LVM2.
9 * This copyrighted material is made available to anyone wishing to use,
10 * modify, copy, or redistribute it subject to the terms and conditions
11 * of the GNU Lesser General Public License v.2.1.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * Only works with powers of 2.
24 static uint32_t _round_up(uint32_t n
, uint32_t size
)
27 return (n
+ size
) & ~size
;
31 static uint32_t _div_up(uint32_t n, uint32_t size)
33 return _round_up(n, size) / size;
38 * Each chunk of metadata should be aligned to
41 static uint32_t _next_base(struct data_area
*area
)
43 return _round_up(area
->base
+ area
->size
, METADATA_ALIGN
);
47 * Quick calculation based on pe_start.
49 static int _adjust_pe_on_disk(struct pv_disk
*pvd
)
51 uint32_t pe_start
= pvd
->pe_start
<< SECTOR_SHIFT
;
53 if (pe_start
< pvd
->pe_on_disk
.base
+ pvd
->pe_on_disk
.size
)
56 pvd
->pe_on_disk
.size
= pe_start
- pvd
->pe_on_disk
.base
;
60 static void _calc_simple_layout(struct pv_disk
*pvd
)
62 pvd
->pv_on_disk
.base
= METADATA_BASE
;
63 pvd
->pv_on_disk
.size
= PV_SIZE
;
65 pvd
->vg_on_disk
.base
= _next_base(&pvd
->pv_on_disk
);
66 pvd
->vg_on_disk
.size
= VG_SIZE
;
68 pvd
->pv_uuidlist_on_disk
.base
= _next_base(&pvd
->vg_on_disk
);
69 pvd
->pv_uuidlist_on_disk
.size
= MAX_PV
* NAME_LEN
;
71 pvd
->lv_on_disk
.base
= _next_base(&pvd
->pv_uuidlist_on_disk
);
72 pvd
->lv_on_disk
.size
= MAX_LV
* sizeof(struct lv_disk
);
74 pvd
->pe_on_disk
.base
= _next_base(&pvd
->lv_on_disk
);
75 pvd
->pe_on_disk
.size
= pvd
->pe_total
* sizeof(struct pe_disk
);
78 static int _check_vg_limits(struct disk_list
*dl
)
80 if (dl
->vgd
.lv_max
> MAX_LV
) {
81 log_error("MaxLogicalVolumes of %d exceeds format limit of %d "
82 "for VG '%s'", dl
->vgd
.lv_max
, MAX_LV
- 1,
87 if (dl
->vgd
.pv_max
> MAX_PV
) {
88 log_error("MaxPhysicalVolumes of %d exceeds format limit of %d "
89 "for VG '%s'", dl
->vgd
.pv_max
, MAX_PV
- 1,
98 * This assumes pe_count and pe_start have already
99 * been calculated correctly.
101 int calculate_layout(struct disk_list
*dl
)
103 struct pv_disk
*pvd
= &dl
->pvd
;
105 _calc_simple_layout(pvd
);
106 if (!_adjust_pe_on_disk(pvd
)) {
107 log_error("Insufficient space for metadata and PE's.");
111 if (!_check_vg_limits(dl
))
118 * The number of extents that can fit on a disk is metadata format dependant.
119 * pe_start is any existing value for pe_start
121 int calculate_extent_count(struct physical_volume
*pv
, uint32_t extent_size
,
122 uint32_t max_extent_count
, uint64_t pe_start
)
124 struct pv_disk
*pvd
= dm_malloc(sizeof(*pvd
));
131 * Guess how many extents will fit, bearing in mind that
132 * one is going to be knocked off at the start of the
135 if (max_extent_count
)
136 pvd
->pe_total
= max_extent_count
+ 1;
138 pvd
->pe_total
= (pv
->size
/ extent_size
);
140 if (pvd
->pe_total
< PE_SIZE_PV_SIZE_REL
) {
141 log_error("Too few extents on %s. Try smaller extent size.",
149 _calc_simple_layout(pvd
);
150 end
= ((pvd
->pe_on_disk
.base
+ pvd
->pe_on_disk
.size
+
151 SECTOR_SIZE
- 1) >> SECTOR_SHIFT
);
153 if (pe_start
&& end
< pe_start
)
156 pvd
->pe_start
= _round_up(end
, LVM1_PE_ALIGN
);
158 } while ((pvd
->pe_start
+ (pvd
->pe_total
* extent_size
))
161 if (pvd
->pe_total
> MAX_PE_TOTAL
) {
162 log_error("Metadata extent limit (%u) exceeded for %s - "
163 "%u required", MAX_PE_TOTAL
, pv_dev_name(pv
),
169 pv
->pe_count
= pvd
->pe_total
;
170 pv
->pe_start
= pvd
->pe_start
;
171 /* We can't set pe_size here without breaking LVM1 compatibility */