dbcheck.c

来自「db.* (pronounced dee-be star) is an adva」· C语言 代码 · 共 2,087 行 · 第 1/5 页

C
2,087
字号
        if ((ts_creat > ts_file) || (ts_modif > ts_file))        {            if (print)                pr_err(BAD_RSTP, NULL, dbi, task);        }    }    oip = dbi->owners + rid;    for (i = 0; i < oip->cnt; i++)    {                                   /* For sets this rid owns */        sip = oip->lst + i;        if (sip->stampd)        {            memcpy((char *) &ts_modif, rec + sip->setoff + 3 * sizeof(F_ADDR),                   sizeof(ts_modif));            if (ts_modif > ts_file)            {                if (print)                    pr_err(BAD_SSTP, &oip->lst[i].setno, dbi, task);            }        }    }}/**************************************************************************//**************************************************************************//*                             Set Checks                                 *//**************************************************************************//**************************************************************************//****************************************************************************    Check consistency of sets which this record owns*/static int chk_own(    char *orec,    short orid,    DB_ADDR odba,    DBINFO *dbi,    DB_TASK *task){    int                     status = S_OKAY;    SET                     set;    MEMBER                  memptr;    F_ADDR                  mcnt;    int                     i;    ERR_PDBA                pdba;    ERR_STYP                styp;    ERR_SCNT                scnt;    register DB_ADDR        mdba,                            prev_mdba;    register REC_SET_INFO  *oip;    register SET_INFO      *sip;    register char          *bp;    static CHKREC chk = {BAD_OMEM, BAD_OMDL, 0, BAD_OMRC, BAD_OMRC, EOF,                         NULL, 0, 0, 0, 0};    oip = dbi->owners + orid;    for (i = 0; i < oip->cnt; i++)    {                                   /* For sets this rid owns */        sip = oip->lst + i;        /* copy the set structure from the record */        memcpy((char *) &set, orec + sip->setoff, sizeof(SET));        pdba.setno = styp.setno = scnt.setno = sip->setno;        if (dbi->opts->counts)            dbi->set_cnt[sip->setno] += set.members;        /* check the validity of the first and last pointers */        if (chk_dba(set.last, dbi, task) != S_OKAY)        {            pdba.dba = set.last;            pr_err(BAD_OLST, &pdba, dbi, task);        }        if (chk_dba(set.first, dbi, task) != S_OKAY)        {            pdba.dba = set.first;            pr_err(BAD_OFST, &pdba, dbi, task);            continue;                     /* Must have good first pointer */        }        /* get the DB_ADDR of the first member */        mcnt = 0;        mdba = set.first;        prev_mdba = NULL_DBA;        /* scan all members in this set */        while (mdba != NULL_DBA)        {            pdba.dba = styp.dba = mdba;            if (++mcnt > set.members)            {                pr_err(BAD_LOOP, &pdba, dbi, task);                break;            }            if ((status = chk_rec(mdba, NULL, (char *) &pdba, &chk, dbi, task)) != S_OKAY)                return (status);            if (!chk.good)            {                if (prev_mdba != NULL_DBA)                {                    pdba.dba = prev_mdba;                    vtprintf(DB_TEXT("    (last good member-dba=%s)\n"), pr_dba(&pdba.dba));                }                break;            }            if ((sip = val_mtype(sip->setno, chk.rid, dbi->members, task)) == NULL)            {                styp.rid = chk.rid;                pr_err(BAD_OMTP, &styp, dbi, task);                break;            }            /* obtain the member pointers */            bp = chk.pgptr + sip->memoff;            memcpy((char *) &memptr, bp, sizeof(MEMBER));            /* make sure that the owner pointers match up */            if (memptr.owner != odba)                pr_err(BAD_OMOW, &pdba, dbi, task);            /* if this is the first member, the PREV pointer must be null */            if ((mdba == set.first) && (memptr.prev != NULL_DBA))            {                pr_err(BAD_MFPN, &pdba, dbi, task);            }            else if (memptr.prev != prev_mdba)            {                /* the previous pointer should point the the previous member */                pr_err(BAD_MNPW, &pdba, dbi, task);                pdba.dba = prev_mdba;                vtprintf(DB_TEXT("    (last good member-dba=%s)\n"), pr_dba(&pdba.dba));            }            /* if this is the last member, the NEXT pointer must be null */            if ((mdba == set.last) && (memptr.next != NULL_DBA))            {                pr_err(BAD_MLNN, &pdba, dbi, task);                break;            }            /* point to the next member */            prev_mdba = mdba;            mdba = memptr.next;        }                                /* end scan all members in this set */        /* verify the membership count */        if (mcnt != set.members)        {            scnt.owncnt = set.members;            scnt.memcnt = mcnt;            pr_err(BAD_OCNT, &scnt, dbi, task);        }    }                 /* end scan sets which are owned by this record type */    return (S_OKAY);}/***************************************************************************    Check consistency of sets which this record is a member of*/static int chk_mem(    char *mrec,    short mrid,    DB_ADDR mdba,    DBINFO *dbi,    DB_TASK *task){    int                     status = S_OKAY;    MEMBER                  memptr;    MEMBER                  prev_memptr;    MEMBER                  next_memptr;    SET                     set;    ERR_PDBA                pdba;    ERR_STYP                styp;    register int            i;    register REC_SET_INFO  *mip;    register SET_INFO      *sip, *tsip;    register char          *bp;    static CHKREC chk = {BAD_MOPB, BAD_MODL, 0, BAD_MORC, BAD_MORC, EOF,                         NULL, 0, 0, 0, 0};    static CHKREC ptrchk = {0, 0, 0, 0, 0, EOF, NULL, 0, 0, 0, 0};            /* used to check next and prev pointers w/i set.  Don't report               errors here because they will be duplicates of an error               reported elsewhere. */    mip = dbi->members + mrid;    for (i = 0; i < mip->cnt; i++)    {                                   /* Sets of which rid is a member */        sip = mip->lst + i;        /* copy member set into structure */        memcpy((char *) &memptr, mrec + sip->memoff, sizeof(MEMBER));        pdba.setno = styp.setno = sip->setno;        pdba.dba = styp.dba = memptr.owner;        if (memptr.owner == NULL_DBA)        {                                /* if the owner pointer is null */            /* if either the next or prev pointers are non-null */            if (memptr.prev != NULL_DBA || memptr.next != NULL_DBA)                pr_err(BAD_MONL, &pdba, dbi, task);        }        else        {            if ((status = chk_rec(memptr.owner, NULL, (char *) &pdba, &chk, dbi, task)) != S_OKAY)                return (status);            if (!chk.good)                continue;            if (chk.rid != sip->ownrid)            {                styp.rid = chk.rid;                pr_err(BAD_MOIN, &styp, dbi, task);                continue;            }            /* get the set pointers */            bp = chk.pgptr + sip->setoff;            memcpy((char *) &set, bp, sizeof(SET));            /* make sure the first pointer points to this record */            if (memptr.prev == NULL_DBA)            {                if (set.first != mdba)                     pr_err(BAD_MNPP, &sip->setno, dbi, task);            }            else            {                /* read the .prev record */                if ((status = chk_rec(memptr.prev, NULL, (char *) &pdba, &ptrchk, dbi, task)) != S_OKAY)                     return (status);                /* check for valid record type */                if ( (tsip = val_mtype(sip->setno, ptrchk.rid, dbi->members, task)) == NULL)                {                     pdba.dba = memptr.prev;                     pr_err(BAD_OMPP, &pdba, dbi, task);                     pdba.dba = memptr.owner;                }                else                {                     /* make sure that prevrecord.next points to this record */                     memcpy((char *) &prev_memptr, (ptrchk.pgptr + tsip->memoff), sizeof(MEMBER));                     if (prev_memptr.next != mdba)                          pr_err(BAD_SETP, &pdba, dbi, task);                }            }                        /* make sure the last pointer points to this record */            if (memptr.next == NULL_DBA)            {                if (set.last != mdba)                     pr_err(BAD_MNNP, &sip->setno, dbi, task);            }            else            {                /* read the .next record */                if ((status = chk_rec(memptr.next, NULL, (char *) &pdba, &ptrchk, dbi, task)) != S_OKAY)                     return (status);                /* check for valid record type */                if ( (tsip = val_mtype(sip->setno, ptrchk.rid, dbi->members, task)) == NULL)                {                     pdba.dba = memptr.next;                     pr_err(BAD_OMEM, &pdba, dbi, task);                     pdba.dba = memptr.owner;                }                else                {                     /* make sure that nextrecord.prev points to this record */                     memcpy((char *) &next_memptr, (ptrchk.pgptr + tsip->memoff), sizeof(MEMBER));                     if (next_memptr.prev != mdba)                          pr_err(BAD_SETN, &pdba, dbi, task);                }            }        }    }    return (S_OKAY);}/***************************************************************************    Locate the member table entry for this record type*/static SET_INFO *val_mtype(    int st,    short mrid,    REC_SET_INFO *meminfo,    DB_TASK *task){    register int            i;    register REC_SET_INFO  *mip;    register SET_INFO      *sip;    if (mrid < 0 || mrid >= task->size_rt)        return (NULL);    mip = meminfo + mrid;    for (i = 0; i < mip->cnt; i++)    {        sip = mip->lst + i;        if (sip->setno == st)            return (sip);    }    return (NULL);}/***************************************************************************//***************************************************************************//*                            Key File Checks                              *//***************************************************************************//***************************************************************************//**************************************************************************    Perform key file consistency check*/static int key_file(    FILE_NO fno,    DBINFO *dbi,    DB_TASK *task){    int               status;    register long     m;    register int      slots;    F_ADDR            top;    KEYINFO           keyinfo;    stat_report(fno, 0, dbi, task);    if ((status = read_del_chain(fno, dbi, task)) != S_OKAY)        return (status);    memset(&keyinfo, 0, sizeof(KEYINFO));    keyinfo.oldno = -1;    keyinfo.slot_len = task->file_table[fno].ft_slsize;    keyinfo.kdup.frst_slot = TRUE;    top = dbi->tops[fno] - 1L;    slots = task->file_table[fno].ft_slots;    for (m = slots / 2, keyinfo.max_levl = 1; m < top * slots; m *= slots / 2)        keyinfo.max_levl++;    /* set node number to be specified in error reports */    dbi->errinfo->addr = 1;    status = dbi->opts->keyscan ?        scan_key(fno, ROOT_ADDR, 1, &keyinfo, dbi, task) :        walk_key(fno, &keyinfo, dbi, task);    if (status != S_OKAY)        return (status);    if (keyinfo.kdup.in_series == TRUE)    {        vtprintf(DB_TEXT("   (total of %ld occurrences of above duplicated value)\n\n"),         keyinfo.kdup.count);    }    if (dbi->opts->keyscan)    {        if ((status = chk_pglst(fno, dbi, task)) != S_OKAY)            dberr(status);    }    delete_temp_files(dbi->pcache);    return (S_OKAY);}/***************************************************************************    Check a key file in page sequential order    (Note: it doesn't check the tree structure at all)*/static int walk_key(    FILE_NO fno,    KEYINFO *ki,    DBINFO *dbi,    DB_TASK *task){    int status = S_OKAY;    register F_ADDR page;    F_ADDR top = dbi->tops[fno] - 1L;    /* This function only gets called if the -k (keyscan) option was not       specified. Walk through all the nodes in the file in physical order,       without recursive calls to check b-tree structure.    */    for (page = ROOT_ADDR; page <= top; page++)    {        /* set node number to be specified in error reports */        dbi->errinfo->addr = page;        /* check this node only - no recursion, as keyscan option is off */        if ((status = chk_node(fno, page, (short) 0, ki, dbi, task)) != S_OKAY)            return (status);    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?