]>
sourceware.org Git - lvm2.git/blob - lib/format1/layout.c
2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
5 * This file is part of LVM2.
7 * This copyrighted material is made available to anyone wishing to use,
8 * modify, copy, or redistribute it subject to the terms and conditions
9 * of the GNU Lesser General Public License v.2.1.
11 * You should have received a copy of the GNU Lesser General Public License
12 * along with this program; if not, write to the Free Software Foundation,
13 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Only works with powers of 2.
22 static uint32_t _round_up(uint32_t n
, uint32_t size
)
25 return (n
+ size
) & ~size
;
29 static uint32_t _div_up(uint32_t n, uint32_t size)
31 return _round_up(n, size) / size;
36 * Each chunk of metadata should be aligned to
39 static uint32_t _next_base(struct data_area
*area
)
41 return _round_up(area
->base
+ area
->size
, METADATA_ALIGN
);
45 * Quick calculation based on pe_start.
47 static int _adjust_pe_on_disk(struct pv_disk
*pvd
)
49 uint32_t pe_start
= pvd
->pe_start
<< SECTOR_SHIFT
;
51 if (pe_start
< pvd
->pe_on_disk
.base
+ pvd
->pe_on_disk
.size
)
54 pvd
->pe_on_disk
.size
= pe_start
- pvd
->pe_on_disk
.base
;
58 static void _calc_simple_layout(struct pv_disk
*pvd
)
60 pvd
->pv_on_disk
.base
= METADATA_BASE
;
61 pvd
->pv_on_disk
.size
= PV_SIZE
;
63 pvd
->vg_on_disk
.base
= _next_base(&pvd
->pv_on_disk
);
64 pvd
->vg_on_disk
.size
= VG_SIZE
;
66 pvd
->pv_uuidlist_on_disk
.base
= _next_base(&pvd
->vg_on_disk
);
67 pvd
->pv_uuidlist_on_disk
.size
= MAX_PV
* NAME_LEN
;
69 pvd
->lv_on_disk
.base
= _next_base(&pvd
->pv_uuidlist_on_disk
);
70 pvd
->lv_on_disk
.size
= MAX_LV
* sizeof(struct lv_disk
);
72 pvd
->pe_on_disk
.base
= _next_base(&pvd
->lv_on_disk
);
73 pvd
->pe_on_disk
.size
= pvd
->pe_total
* sizeof(struct pe_disk
);
76 static int _check_vg_limits(struct disk_list
*dl
)
78 if (dl
->vgd
.lv_max
> MAX_LV
) {
79 log_error("MaxLogicalVolumes of %d exceeds format limit of %d "
80 "for VG '%s'", dl
->vgd
.lv_max
, MAX_LV
- 1,
85 if (dl
->vgd
.pv_max
> MAX_PV
) {
86 log_error("MaxPhysicalVolumes of %d exceeds format limit of %d "
87 "for VG '%s'", dl
->vgd
.pv_max
, MAX_PV
- 1,
96 * This assumes pe_count and pe_start have already
97 * been calculated correctly.
99 int calculate_layout(struct disk_list
*dl
)
101 struct pv_disk
*pvd
= &dl
->pvd
;
103 _calc_simple_layout(pvd
);
104 if (!_adjust_pe_on_disk(pvd
)) {
105 log_error("Insufficient space for metadata and PE's.");
109 if (!_check_vg_limits(dl
))
116 * The number of extents that can fit on a disk is metadata format dependant.
117 * pe_start is any existing value for pe_start
119 int calculate_extent_count(struct physical_volume
*pv
, uint32_t extent_size
,
120 uint32_t max_extent_count
, uint64_t pe_start
)
122 struct pv_disk
*pvd
= dm_malloc(sizeof(*pvd
));
129 * Guess how many extents will fit, bearing in mind that
130 * one is going to be knocked off at the start of the
133 if (max_extent_count
)
134 pvd
->pe_total
= max_extent_count
+ 1;
136 pvd
->pe_total
= (pv
->size
/ extent_size
);
138 if (pvd
->pe_total
< PE_SIZE_PV_SIZE_REL
) {
139 log_error("Too few extents on %s. Try smaller extent size.",
147 _calc_simple_layout(pvd
);
148 end
= ((pvd
->pe_on_disk
.base
+ pvd
->pe_on_disk
.size
+
149 SECTOR_SIZE
- 1) >> SECTOR_SHIFT
);
151 if (pe_start
&& end
< pe_start
)
154 pvd
->pe_start
= _round_up(end
, LVM1_PE_ALIGN
);
156 } while ((pvd
->pe_start
+ (pvd
->pe_total
* extent_size
))
159 if (pvd
->pe_total
> MAX_PE_TOTAL
) {
160 log_error("Metadata extent limit (%u) exceeded for %s - "
161 "%u required", MAX_PE_TOTAL
, pv_dev_name(pv
),
167 pv
->pe_count
= pvd
->pe_total
;
168 pv
->pe_start
= pvd
->pe_start
;
169 /* We can't set pe_size here without breaking LVM1 compatibility */
This page took 0.041193 seconds and 5 git commands to generate.