249
static int _merge_free_pv_segment(struct pv_segment *peg)
252
struct pv_segment *merge_peg;
255
log_error(INTERNAL_ERROR
256
"_merge_free_pv_seg called on a"
257
" segment that is not free.");
263
* Should we free the list element once it is deleted
264
* from the list? I think not. It is likely part of
267
/* Attempt to merge with Free space before */
268
if ((l = dm_list_prev(&peg->pv->segments, &peg->list))) {
269
merge_peg = dm_list_item(l, struct pv_segment);
270
if (!merge_peg->lvseg) {
271
merge_peg->len += peg->len;
272
dm_list_del(&peg->list);
277
/* Attempt to merge with Free space after */
278
if ((l = dm_list_next(&peg->pv->segments, &peg->list))) {
279
merge_peg = dm_list_item(l, struct pv_segment);
280
if (!merge_peg->lvseg) {
281
peg->len += merge_peg->len;
282
dm_list_del(&merge_peg->list);
294
* WARNING: When release_pv_segment is called, the freed space may be
295
* merged into the 'pv_segment's before and after it in the
296
* list if they are also free. Thus, any iterators of the
297
* 'pv->segments' list that call this function must be aware
298
* that the list can change in a way that is unsafe even for
299
* *_safe iterators. Restart the iterator in these cases.
301
* Returns: 1 on success, 0 on failure
249
303
int release_pv_segment(struct pv_segment *peg, uint32_t area_reduction)
306
struct pv_segment *merge_peg;
251
308
if (!peg->lvseg) {
252
309
log_error("release_pv_segment with unallocated segment: "
253
310
"%s PE %" PRIu32, pv_dev_name(peg->pv), peg->pe);
271
326
area_reduction, NULL))
329
/* The segment after 'peg' now holds free space, try to merge it */
330
if ((l = dm_list_next(&peg->pv->segments, &peg->list))) {
331
merge_peg = dm_list_item(l, struct pv_segment);
332
return _merge_free_pv_segment(merge_peg);
814
info = lvmcache_info_from_pvid(dev->pvid, 1);
752
816
if (!dev_test_excl(dev)) {
753
817
/* FIXME Detect whether device-mapper is still using the device */
754
818
log_error("Can't open %s exclusively - not removing. "