1: # include <ingres.h> 2: # include <access.h> 3: # include <aux.h> 4: # include <lock.h> 5: # include <sccs.h> 6: 7: SCCSID(@(#)add_ovflo.c 8.2 2/8/85) 8: 9: /* 10: ** ADD_OVFLO -- Allocates an overflow page which will be 11: ** attached to current page. TID must be for current page. 12: ** TID will be updated to id of new overflow page. 13: ** 14: ** Parameters: 15: ** dx - descriptor for relation 16: ** tid - tid for current page 17: ** 18: ** Side Effects: 19: ** tid is updated to id of new overflow page 20: ** 21: ** Trace Flags: 22: ** 26.3 23: ** 24: ** Returns: 25: ** 0 - success 26: ** -1 (NOBUFFER) can't get buffer for overflow page 27: ** -2 (NOSETUP) can't set up overflow page 28: ** -3 (NOGETCURRENT) can't get the current page 29: ** -4 (NORMVMAIN) can't remove main page 30: ** -5 (NOGETOVFLO) can't get the overflow page 31: ** 32: */ 33: 34: add_ovflo(dx, tid) 35: DESC *dx; 36: TID *tid; 37: { 38: register DESC *d; 39: register struct accbuf *b; 40: extern struct accbuf *choose_buf(); 41: register int lk; 42: int i; 43: long mpage, newpage; 44: TID tidx; 45: 46: d = dx; 47: # ifdef xATR2 48: if (tTf(26, 3)) 49: printf("ADD_OVFLO:\n"); 50: # endif 51: 52: /* 53: ** save main page pointer so that it may be used when 54: ** setting up new overflow page. 55: */ 56: mpage = Acc_head->mainpg; 57: 58: if (lk = (Acclock && (d->reldum.relstat & S_CONCUR) && (d->relopn < 0 ))) 59: { 60: setcsl(Acc_head->rel_tupid); 61: Acclock = FALSE; 62: } 63: 64: /* 65: ** Determine last page of the relation 66: */ 67: last_page(d, &tidx, Acc_head); 68: pluck_page(&tidx, &newpage); 69: newpage++; 70: 71: /* 72: ** choose an available buffer as victim for setting up 73: ** overflow page. 74: */ 75: if ((b = choose_buf(d, newpage)) == NULL) 76: { 77: if (lk) 78: { 79: Acclock = TRUE; 80: unlcs(Acc_head->rel_tupid); 81: } 82: return(NOBUFFER); 83: } 84: 85: /* 86: ** setup overflow page 87: */ 88: 89: b->mainpg = mpage; 90: b->ovflopg = 0; 91: b->thispage = newpage; 92: b->linetab[0] = (int) b->firstup - (int) b; 93: b->nxtlino = 0; 94: b->bufstatus |= BUF_DIRTY; 95: if (pageflush(b)) 96: return (NOSETUP); 97: 98: /* 99: ** now that overflow page has successfully been written, 100: ** get the old current page back and link the new overflow page 101: ** to it. 102: ** If the relation is a heap then don't leave the old main 103: ** page around in the buffers. This is done on the belief 104: ** that it will never be accessed again. 105: */ 106: 107: if (get_page(d, tid)) 108: return (NOGETCURRENT); 109: Acc_head->ovflopg = newpage; 110: Acc_head->bufstatus |= BUF_DIRTY; 111: i = pageflush(Acc_head); 112: if (lk) 113: { 114: Acclock = TRUE; 115: unlcs(Acc_head->rel_tupid); 116: } 117: if (i) 118: return (NORMVMAIN); 119: if (abs(d->reldum.relspec) == M_HEAP) 120: resetacc(Acc_head); /* no error is possible */ 121: 122: /* 123: ** now bring the overflow page back and make it current. 124: ** if the overflow page is still in AM cache, then this will not 125: ** cause any disk activity. 126: */ 127: 128: stuff_page(tid, &newpage); 129: if (get_page(d, tid)) 130: return (NOGETOVFLO); 131: return (0); 132: }