diff options
Diffstat (limited to 'src/backend/storage/page/bufpage.c')
-rw-r--r-- | src/backend/storage/page/bufpage.c | 670 |
1 files changed, 349 insertions, 321 deletions
diff --git a/src/backend/storage/page/bufpage.c b/src/backend/storage/page/bufpage.c index 98d1c59d5f0..75e1b5da9e7 100644 --- a/src/backend/storage/page/bufpage.c +++ b/src/backend/storage/page/bufpage.c @@ -1,13 +1,13 @@ /*------------------------------------------------------------------------- * * bufpage.c-- - * POSTGRES standard buffer page code. + * POSTGRES standard buffer page code. * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/page/bufpage.c,v 1.8 1997/08/24 23:07:30 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/page/bufpage.c,v 1.9 1997/09/07 04:49:06 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -26,341 +26,368 @@ #include "lib/qsort.h" -static void PageIndexTupleDeleteAdjustLinePointers(PageHeader phdr, - char *location, Size size); +static void +PageIndexTupleDeleteAdjustLinePointers(PageHeader phdr, + char *location, Size size); -static bool PageManagerShuffle = true; /* default is shuffle mode */ +static bool PageManagerShuffle = true; /* default is shuffle mode */ /* ---------------------------------------------------------------- - * Page support functions + * Page support functions * ---------------------------------------------------------------- */ /* * PageInit -- - * Initializes the contents of a page. + * Initializes the contents of a page. */ void PageInit(Page page, Size pageSize, Size specialSize) { - PageHeader p = (PageHeader) page; - - Assert(pageSize == BLCKSZ); - Assert(pageSize > - specialSize + sizeof(PageHeaderData) - sizeof(ItemIdData)); - - specialSize = DOUBLEALIGN(specialSize); - - p->pd_lower = sizeof(PageHeaderData) - sizeof(ItemIdData); - p->pd_upper = pageSize - specialSize; - p->pd_special = pageSize - specialSize; - PageSetPageSize(page, pageSize); + PageHeader p = (PageHeader) page; + + Assert(pageSize == BLCKSZ); + Assert(pageSize > + specialSize + sizeof(PageHeaderData) - sizeof(ItemIdData)); + + specialSize = DOUBLEALIGN(specialSize); + + p->pd_lower = sizeof(PageHeaderData) - sizeof(ItemIdData); + p->pd_upper = pageSize - specialSize; + p->pd_special = pageSize - specialSize; + PageSetPageSize(page, pageSize); } /* * PageAddItem -- - * Adds item to the given page. + * Adds item to the given page. * * Note: - * This does not assume that the item resides on a single page. - * It is the responsiblity of the caller to act appropriately - * depending on this fact. The "pskip" routines provide a - * friendlier interface, in this case. - * - * This does change the status of any of the resources passed. - * The semantics may change in the future. + * This does not assume that the item resides on a single page. + * It is the responsiblity of the caller to act appropriately + * depending on this fact. The "pskip" routines provide a + * friendlier interface, in this case. + * + * This does change the status of any of the resources passed. + * The semantics may change in the future. * - * This routine should probably be combined with others? + * This routine should probably be combined with others? */ /* ---------------- - * PageAddItem + * PageAddItem * - * add an item to a page. + * add an item to a page. * - * Notes on interface: - * If offsetNumber is valid, shuffle ItemId's down to make room - * to use it, if PageManagerShuffle is true. If PageManagerShuffle is - * false, then overwrite the specified ItemId. (PageManagerShuffle is - * true by default, and is modified by calling PageManagerModeSet.) - * If offsetNumber is not valid, then assign one by finding the first - * one that is both unused and deallocated. + * Notes on interface: + * If offsetNumber is valid, shuffle ItemId's down to make room + * to use it, if PageManagerShuffle is true. If PageManagerShuffle is + * false, then overwrite the specified ItemId. (PageManagerShuffle is + * true by default, and is modified by calling PageManagerModeSet.) + * If offsetNumber is not valid, then assign one by finding the first + * one that is both unused and deallocated. * - * NOTE: If offsetNumber is valid, and PageManagerShuffle is true, it - * is assumed that there is room on the page to shuffle the ItemId's - * down by one. + * NOTE: If offsetNumber is valid, and PageManagerShuffle is true, it + * is assumed that there is room on the page to shuffle the ItemId's + * down by one. * ---------------- */ OffsetNumber PageAddItem(Page page, - Item item, - Size size, - OffsetNumber offsetNumber, - ItemIdFlags flags) + Item item, + Size size, + OffsetNumber offsetNumber, + ItemIdFlags flags) { - register i; - Size alignedSize; - Offset lower; - Offset upper; - ItemId itemId; - ItemId fromitemId, toitemId; - OffsetNumber limit; - - bool shuffled = false; - - /* - * Find first unallocated offsetNumber - */ - limit = OffsetNumberNext(PageGetMaxOffsetNumber(page)); - - /* was offsetNumber passed in? */ - if (OffsetNumberIsValid(offsetNumber)) { - if (PageManagerShuffle == true) { - /* shuffle ItemId's (Do the PageManager Shuffle...) */ - for (i = (limit - 1); i >= offsetNumber; i--) { - fromitemId = &((PageHeader)page)->pd_linp[i - 1]; - toitemId = &((PageHeader)page)->pd_linp[i]; - *toitemId = *fromitemId; - } - shuffled = true; /* need to increase "lower" */ - } else { /* overwrite mode */ - itemId = &((PageHeader)page)->pd_linp[offsetNumber - 1]; - if (((*itemId).lp_flags & LP_USED) || - ((*itemId).lp_len != 0)) { - elog(WARN, "PageAddItem: tried overwrite of used ItemId"); - return (InvalidOffsetNumber); - } + register i; + Size alignedSize; + Offset lower; + Offset upper; + ItemId itemId; + ItemId fromitemId, + toitemId; + OffsetNumber limit; + + bool shuffled = false; + + /* + * Find first unallocated offsetNumber + */ + limit = OffsetNumberNext(PageGetMaxOffsetNumber(page)); + + /* was offsetNumber passed in? */ + if (OffsetNumberIsValid(offsetNumber)) + { + if (PageManagerShuffle == true) + { + /* shuffle ItemId's (Do the PageManager Shuffle...) */ + for (i = (limit - 1); i >= offsetNumber; i--) + { + fromitemId = &((PageHeader) page)->pd_linp[i - 1]; + toitemId = &((PageHeader) page)->pd_linp[i]; + *toitemId = *fromitemId; + } + shuffled = true; /* need to increase "lower" */ + } + else + { /* overwrite mode */ + itemId = &((PageHeader) page)->pd_linp[offsetNumber - 1]; + if (((*itemId).lp_flags & LP_USED) || + ((*itemId).lp_len != 0)) + { + elog(WARN, "PageAddItem: tried overwrite of used ItemId"); + return (InvalidOffsetNumber); + } + } } - } else { /* offsetNumber was not passed in, so find one */ - /* look for "recyclable" (unused & deallocated) ItemId */ - for (offsetNumber = 1; offsetNumber < limit; offsetNumber++) { - itemId = &((PageHeader)page)->pd_linp[offsetNumber - 1]; - if ((((*itemId).lp_flags & LP_USED) == 0) && - ((*itemId).lp_len == 0)) - break; + else + { /* offsetNumber was not passed in, so find + * one */ + /* look for "recyclable" (unused & deallocated) ItemId */ + for (offsetNumber = 1; offsetNumber < limit; offsetNumber++) + { + itemId = &((PageHeader) page)->pd_linp[offsetNumber - 1]; + if ((((*itemId).lp_flags & LP_USED) == 0) && + ((*itemId).lp_len == 0)) + break; + } } - } - if (offsetNumber > limit) - lower = (Offset) (((char *) (&((PageHeader)page)->pd_linp[offsetNumber])) - ((char *) page)); - else if (offsetNumber == limit || shuffled == true) - lower = ((PageHeader)page)->pd_lower + sizeof (ItemIdData); - else - lower = ((PageHeader)page)->pd_lower; - - alignedSize = DOUBLEALIGN(size); - - upper = ((PageHeader)page)->pd_upper - alignedSize; - - if (lower > upper) { - return (InvalidOffsetNumber); - } - - itemId = &((PageHeader)page)->pd_linp[offsetNumber - 1]; - (*itemId).lp_off = upper; - (*itemId).lp_len = size; - (*itemId).lp_flags = flags; - memmove((char *)page + upper, item, size); - ((PageHeader)page)->pd_lower = lower; - ((PageHeader)page)->pd_upper = upper; - - return (offsetNumber); + if (offsetNumber > limit) + lower = (Offset) (((char *) (&((PageHeader) page)->pd_linp[offsetNumber])) - ((char *) page)); + else if (offsetNumber == limit || shuffled == true) + lower = ((PageHeader) page)->pd_lower + sizeof(ItemIdData); + else + lower = ((PageHeader) page)->pd_lower; + + alignedSize = DOUBLEALIGN(size); + + upper = ((PageHeader) page)->pd_upper - alignedSize; + + if (lower > upper) + { + return (InvalidOffsetNumber); + } + + itemId = &((PageHeader) page)->pd_linp[offsetNumber - 1]; + (*itemId).lp_off = upper; + (*itemId).lp_len = size; + (*itemId).lp_flags = flags; + memmove((char *) page + upper, item, size); + ((PageHeader) page)->pd_lower = lower; + ((PageHeader) page)->pd_upper = upper; + + return (offsetNumber); } /* * PageGetTempPage -- - * Get a temporary page in local memory for special processing + * Get a temporary page in local memory for special processing */ Page PageGetTempPage(Page page, Size specialSize) { - Size pageSize; - Size size; - Page temp; - PageHeader thdr; - - pageSize = PageGetPageSize(page); - - if ((temp = (Page) palloc(pageSize)) == (Page) NULL) - elog(FATAL, "Cannot allocate %d bytes for temp page.", pageSize); - thdr = (PageHeader) temp; - - /* copy old page in */ - memmove(temp, page, pageSize); - - /* clear out the middle */ - size = (pageSize - sizeof(PageHeaderData)) + sizeof(ItemIdData); - size -= DOUBLEALIGN(specialSize); - memset((char *) &(thdr->pd_linp[0]), 0, size); - - /* set high, low water marks */ - thdr->pd_lower = sizeof (PageHeaderData) - sizeof (ItemIdData); - thdr->pd_upper = pageSize - DOUBLEALIGN(specialSize); - - return (temp); + Size pageSize; + Size size; + Page temp; + PageHeader thdr; + + pageSize = PageGetPageSize(page); + + if ((temp = (Page) palloc(pageSize)) == (Page) NULL) + elog(FATAL, "Cannot allocate %d bytes for temp page.", pageSize); + thdr = (PageHeader) temp; + + /* copy old page in */ + memmove(temp, page, pageSize); + + /* clear out the middle */ + size = (pageSize - sizeof(PageHeaderData)) + sizeof(ItemIdData); + size -= DOUBLEALIGN(specialSize); + memset((char *) &(thdr->pd_linp[0]), 0, size); + + /* set high, low water marks */ + thdr->pd_lower = sizeof(PageHeaderData) - sizeof(ItemIdData); + thdr->pd_upper = pageSize - DOUBLEALIGN(specialSize); + + return (temp); } /* * PageRestoreTempPage -- - * Copy temporary page back to permanent page after special processing - * and release the temporary page. + * Copy temporary page back to permanent page after special processing + * and release the temporary page. */ void PageRestoreTempPage(Page tempPage, Page oldPage) { - Size pageSize; - - pageSize = PageGetPageSize(tempPage); - memmove((char *) oldPage, (char *) tempPage, pageSize); - - pfree(tempPage); + Size pageSize; + + pageSize = PageGetPageSize(tempPage); + memmove((char *) oldPage, (char *) tempPage, pageSize); + + pfree(tempPage); } /* * PageGetMaxOffsetNumber -- - * Returns the maximum offset number used by the given page. + * Returns the maximum offset number used by the given page. * - * NOTE: The offset is invalid if the page is non-empty. - * Test whether PageIsEmpty before calling this routine - * and/or using its return value. + * NOTE: The offset is invalid if the page is non-empty. + * Test whether PageIsEmpty before calling this routine + * and/or using its return value. */ OffsetNumber PageGetMaxOffsetNumber(Page page) { - LocationIndex low; - OffsetNumber i; - - low = ((PageHeader) page)->pd_lower; - i = (low - (sizeof(PageHeaderData) - sizeof(ItemIdData))) - / sizeof(ItemIdData); - - return(i); -} + LocationIndex low; + OffsetNumber i; + + low = ((PageHeader) page)->pd_lower; + i = (low - (sizeof(PageHeaderData) - sizeof(ItemIdData))) + / sizeof(ItemIdData); + + return (i); +} /* ---------------- - * itemid stuff for PageRepairFragmentation + * itemid stuff for PageRepairFragmentation * ---------------- */ -struct itemIdSortData { - int offsetindex; /* linp array index */ - ItemIdData itemiddata; +struct itemIdSortData +{ + int offsetindex;/* linp array index */ + ItemIdData itemiddata; }; static int itemidcompare(void *itemidp1, void *itemidp2) { - if (((struct itemIdSortData *)itemidp1)->itemiddata.lp_off == - ((struct itemIdSortData *)itemidp2)->itemiddata.lp_off) - return(0); - else if (((struct itemIdSortData *)itemidp1)->itemiddata.lp_off < - ((struct itemIdSortData *)itemidp2)->itemiddata.lp_off) - return(1); - else - return(-1); + if (((struct itemIdSortData *) itemidp1)->itemiddata.lp_off == + ((struct itemIdSortData *) itemidp2)->itemiddata.lp_off) + return (0); + else if (((struct itemIdSortData *) itemidp1)->itemiddata.lp_off < + ((struct itemIdSortData *) itemidp2)->itemiddata.lp_off) + return (1); + else + return (-1); } /* * PageRepairFragmentation -- - * Frees fragmented space on a page. + * Frees fragmented space on a page. */ void PageRepairFragmentation(Page page) { - int i; - struct itemIdSortData *itemidbase, *itemidptr; - ItemId lp; - int nline, nused; - Offset upper; - Size alignedSize; - - nline = (int16) PageGetMaxOffsetNumber(page); - nused = 0; - for (i=0; i<nline; i++) { - lp = ((PageHeader)page)->pd_linp + i; - if ((*lp).lp_flags & LP_USED) - nused++; - } - - if (nused == 0) { - for (i=0; i<nline; i++) { - lp = ((PageHeader)page)->pd_linp + i; - if ((*lp).lp_len > 0) /* unused, but allocated */ - (*lp).lp_len = 0; /* indicate unused & deallocated */ + int i; + struct itemIdSortData *itemidbase, + *itemidptr; + ItemId lp; + int nline, + nused; + Offset upper; + Size alignedSize; + + nline = (int16) PageGetMaxOffsetNumber(page); + nused = 0; + for (i = 0; i < nline; i++) + { + lp = ((PageHeader) page)->pd_linp + i; + if ((*lp).lp_flags & LP_USED) + nused++; } - - ((PageHeader)page)->pd_upper = ((PageHeader)page)->pd_special; - } else { /* nused != 0 */ - itemidbase = (struct itemIdSortData *) - palloc(sizeof(struct itemIdSortData) * nused); - memset((char *) itemidbase, 0, sizeof(struct itemIdSortData) * nused); - itemidptr = itemidbase; - for (i=0; i<nline; i++) { - lp = ((PageHeader)page)->pd_linp + i; - if ((*lp).lp_flags & LP_USED) { - itemidptr->offsetindex = i; - itemidptr->itemiddata = *lp; - itemidptr++; - } else { - if ((*lp).lp_len > 0) /* unused, but allocated */ - (*lp).lp_len = 0; /* indicate unused & deallocated */ - } + + if (nused == 0) + { + for (i = 0; i < nline; i++) + { + lp = ((PageHeader) page)->pd_linp + i; + if ((*lp).lp_len > 0) /* unused, but allocated */ + (*lp).lp_len = 0; /* indicate unused & deallocated */ + } + + ((PageHeader) page)->pd_upper = ((PageHeader) page)->pd_special; } - - /* sort itemIdSortData array...*/ - pg_qsort((char *) itemidbase, nused, sizeof(struct itemIdSortData), - itemidcompare); - - /* compactify page */ - ((PageHeader)page)->pd_upper = ((PageHeader)page)->pd_special; - - for (i=0, itemidptr = itemidbase; i<nused; i++, itemidptr++) { - lp = ((PageHeader)page)->pd_linp + itemidptr->offsetindex; - alignedSize = DOUBLEALIGN((*lp).lp_len); - upper = ((PageHeader)page)->pd_upper - alignedSize; - memmove((char *) page + upper, - (char *)page + (*lp).lp_off, - (*lp).lp_len); - (*lp).lp_off = upper; - ((PageHeader)page)->pd_upper = upper; + else + { /* nused != 0 */ + itemidbase = (struct itemIdSortData *) + palloc(sizeof(struct itemIdSortData) * nused); + memset((char *) itemidbase, 0, sizeof(struct itemIdSortData) * nused); + itemidptr = itemidbase; + for (i = 0; i < nline; i++) + { + lp = ((PageHeader) page)->pd_linp + i; + if ((*lp).lp_flags & LP_USED) + { + itemidptr->offsetindex = i; + itemidptr->itemiddata = *lp; + itemidptr++; + } + else + { + if ((*lp).lp_len > 0) /* unused, but allocated */ + (*lp).lp_len = 0; /* indicate unused & deallocated */ + } + } + + /* sort itemIdSortData array... */ + pg_qsort((char *) itemidbase, nused, sizeof(struct itemIdSortData), + itemidcompare); + + /* compactify page */ + ((PageHeader) page)->pd_upper = ((PageHeader) page)->pd_special; + + for (i = 0, itemidptr = itemidbase; i < nused; i++, itemidptr++) + { + lp = ((PageHeader) page)->pd_linp + itemidptr->offsetindex; + alignedSize = DOUBLEALIGN((*lp).lp_len); + upper = ((PageHeader) page)->pd_upper - alignedSize; + memmove((char *) page + upper, + (char *) page + (*lp).lp_off, + (*lp).lp_len); + (*lp).lp_off = upper; + ((PageHeader) page)->pd_upper = upper; + } + + pfree(itemidbase); } - - pfree(itemidbase); - } } /* * PageGetFreeSpace -- - * Returns the size of the free (allocatable) space on a page. + * Returns the size of the free (allocatable) space on a page. */ Size PageGetFreeSpace(Page page) { - Size space; - - - space = ((PageHeader)page)->pd_upper - ((PageHeader)page)->pd_lower; - - if (space < sizeof (ItemIdData)) { - return (0); - } - space -= sizeof (ItemIdData); /* XXX not always true */ - - return (space); + Size space; + + + space = ((PageHeader) page)->pd_upper - ((PageHeader) page)->pd_lower; + + if (space < sizeof(ItemIdData)) + { + return (0); + } + space -= sizeof(ItemIdData);/* XXX not always true */ + + return (space); } /* * PageManagerModeSet -- * - * Sets mode to either: ShufflePageManagerMode (the default) or - * OverwritePageManagerMode. For use by access methods code - * for determining semantics of PageAddItem when the offsetNumber - * argument is passed in. + * Sets mode to either: ShufflePageManagerMode (the default) or + * OverwritePageManagerMode. For use by access methods code + * for determining semantics of PageAddItem when the offsetNumber + * argument is passed in. */ void PageManagerModeSet(PageManagerMode mode) { - if (mode == ShufflePageManagerMode) - PageManagerShuffle = true; - else if (mode == OverwritePageManagerMode) - PageManagerShuffle = false; + if (mode == ShufflePageManagerMode) + PageManagerShuffle = true; + else if (mode == OverwritePageManagerMode) + PageManagerShuffle = false; } /* @@ -368,65 +395,64 @@ PageManagerModeSet(PageManagerMode mode) * PageIndexTupleDelete *---------------------------------------------------------------- * - * This routine does the work of removing a tuple from an index page. + * This routine does the work of removing a tuple from an index page. */ void PageIndexTupleDelete(Page page, OffsetNumber offnum) { - PageHeader phdr; - char *addr; - ItemId tup; - Size size; - char *locn; - int nbytes; - int offidx; - - phdr = (PageHeader) page; - - /* change offset number to offset index */ - offidx = offnum - 1; - - tup = PageGetItemId(page, offnum); - size = ItemIdGetLength(tup); - size = DOUBLEALIGN(size); - - /* location of deleted tuple data */ - locn = (char *) (page + ItemIdGetOffset(tup)); - - /* - * First, we want to get rid of the pd_linp entry for the index - * tuple. We copy all subsequent linp's back one slot in the - * array. - */ - - nbytes = phdr->pd_lower - - ((char *)&phdr->pd_linp[offidx + 1] - (char *) phdr); - memmove((char *) &(phdr->pd_linp[offidx]), - (char *) &(phdr->pd_linp[offidx + 1]), - nbytes); - - /* - * Now move everything between the old upper bound (beginning of tuple - * space) and the beginning of the deleted tuple forward, so that - * space in the middle of the page is left free. If we've just deleted - * the tuple at the beginning of tuple space, then there's no need - * to do the copy (and bcopy on some architectures SEGV's if asked - * to move zero bytes). - */ - - /* beginning of tuple space */ - addr = (char *) (page + phdr->pd_upper); - - if (locn != addr) - memmove(addr + size, addr, (int) (locn - addr)); - - /* adjust free space boundary pointers */ - phdr->pd_upper += size; - phdr->pd_lower -= sizeof (ItemIdData); - - /* finally, we need to adjust the linp entries that remain */ - if (!PageIsEmpty(page)) - PageIndexTupleDeleteAdjustLinePointers(phdr, locn, size); + PageHeader phdr; + char *addr; + ItemId tup; + Size size; + char *locn; + int nbytes; + int offidx; + + phdr = (PageHeader) page; + + /* change offset number to offset index */ + offidx = offnum - 1; + + tup = PageGetItemId(page, offnum); + size = ItemIdGetLength(tup); + size = DOUBLEALIGN(size); + + /* location of deleted tuple data */ + locn = (char *) (page + ItemIdGetOffset(tup)); + + /* + * First, we want to get rid of the pd_linp entry for the index tuple. + * We copy all subsequent linp's back one slot in the array. + */ + + nbytes = phdr->pd_lower - + ((char *) &phdr->pd_linp[offidx + 1] - (char *) phdr); + memmove((char *) &(phdr->pd_linp[offidx]), + (char *) &(phdr->pd_linp[offidx + 1]), + nbytes); + + /* + * Now move everything between the old upper bound (beginning of tuple + * space) and the beginning of the deleted tuple forward, so that + * space in the middle of the page is left free. If we've just + * deleted the tuple at the beginning of tuple space, then there's no + * need to do the copy (and bcopy on some architectures SEGV's if + * asked to move zero bytes). + */ + + /* beginning of tuple space */ + addr = (char *) (page + phdr->pd_upper); + + if (locn != addr) + memmove(addr + size, addr, (int) (locn - addr)); + + /* adjust free space boundary pointers */ + phdr->pd_upper += size; + phdr->pd_lower -= sizeof(ItemIdData); + + /* finally, we need to adjust the linp entries that remain */ + if (!PageIsEmpty(page)) + PageIndexTupleDeleteAdjustLinePointers(phdr, locn, size); } /* @@ -434,33 +460,35 @@ PageIndexTupleDelete(Page page, OffsetNumber offnum) * PageIndexTupleDeleteAdjustLinePointers *---------------------------------------------------------------- * - * Once the line pointers and tuple data have been shifted around - * on the page, we need to go down the line pointer vector and - * adjust pointers to reflect new locations. Anything that used - * to be before the deleted tuple's data was moved forward by the - * size of the deleted tuple. + * Once the line pointers and tuple data have been shifted around + * on the page, we need to go down the line pointer vector and + * adjust pointers to reflect new locations. Anything that used + * to be before the deleted tuple's data was moved forward by the + * size of the deleted tuple. * - * This routine does the work of adjusting the line pointers. - * Location is where the tuple data used to lie; size is how - * much space it occupied. We assume that size has been aligned - * as required by the time we get here. + * This routine does the work of adjusting the line pointers. + * Location is where the tuple data used to lie; size is how + * much space it occupied. We assume that size has been aligned + * as required by the time we get here. * - * This routine should never be called on an empty page. + * This routine should never be called on an empty page. */ static void PageIndexTupleDeleteAdjustLinePointers(PageHeader phdr, - char *location, - Size size) + char *location, + Size size) { - int i; - unsigned offset; - - /* location is an index into the page... */ - offset = (unsigned)(location - (char *)phdr); - - for (i = PageGetMaxOffsetNumber((Page) phdr) - 1; i >= 0; i--) { - if (phdr->pd_linp[i].lp_off <= offset) { - phdr->pd_linp[i].lp_off += size; + int i; + unsigned offset; + + /* location is an index into the page... */ + offset = (unsigned) (location - (char *) phdr); + + for (i = PageGetMaxOffsetNumber((Page) phdr) - 1; i >= 0; i--) + { + if (phdr->pd_linp[i].lp_off <= offset) + { + phdr->pd_linp[i].lp_off += size; + } } - } } |