llog.c

来自「lustre 1.6.5 source code」· C语言 代码 · 共 425 行 · 第 1/2 页

C
425
字号
        int rc = 0, index = 1, last_index;        int saved_index = 0, last_called_index = 0;        ENTRY;        LASSERT(llh);        OBD_ALLOC(buf, LLOG_CHUNK_SIZE);        if (!buf)                RETURN(-ENOMEM);        if (cd != NULL) {                last_called_index = cd->first_idx;                index = cd->first_idx + 1;        }        if (cd != NULL && cd->last_idx)                last_index = cd->last_idx;        else                last_index = LLOG_BITMAP_BYTES * 8 - 1;        while (rc == 0) {                struct llog_rec_hdr *rec;                /* skip records not set in bitmap */                while (index <= last_index &&                       !ext2_test_bit(index, llh->llh_bitmap))                        ++index;                LASSERT(index <= last_index + 1);                if (index == last_index + 1)                        break;                CDEBUG(D_OTHER, "index: %d last_index %d\n",                       index, last_index);                /* get the buf with our target record; avoid old garbage */                last_offset = cur_offset;                rc = llog_next_block(loghandle, &saved_index, index,                                     &cur_offset, buf, LLOG_CHUNK_SIZE);                if (rc)                        GOTO(out, rc);                /* NB: when rec->lrh_len is accessed it is already swabbed                 * since it is used at the "end" of the loop and the rec                 * swabbing is done at the beginning of the loop. */                for (rec = (struct llog_rec_hdr *)buf;                     (char *)rec < buf + LLOG_CHUNK_SIZE;                     rec = (struct llog_rec_hdr *)((char *)rec + rec->lrh_len)){                        CDEBUG(D_OTHER, "processing rec 0x%p type %#x\n",                               rec, rec->lrh_type);                        if (LLOG_REC_HDR_NEEDS_SWABBING(rec))                                lustre_swab_llog_rec(rec, NULL);                        CDEBUG(D_OTHER, "after swabbing, type=%#x idx=%d\n",                               rec->lrh_type, rec->lrh_index);                                                if (rec->lrh_index == 0)                                GOTO(out, 0); /* no more records */                        if (rec->lrh_len == 0 || rec->lrh_len >LLOG_CHUNK_SIZE){                                CWARN("invalid length %d in llog record for "                                      "index %d/%d\n", rec->lrh_len,                                      rec->lrh_index, index);                                GOTO(out, rc = -EINVAL);                        }                        if (rec->lrh_index < index) {                                CDEBUG(D_OTHER, "skipping lrh_index %d\n",                                       rec->lrh_index);                                continue;                        }                        CDEBUG(D_OTHER,                                "lrh_index: %d lrh_len: %d (%d remains)\n",                               rec->lrh_index, rec->lrh_len,                               (int)(buf + LLOG_CHUNK_SIZE - (char *)rec));                        loghandle->lgh_cur_idx = rec->lrh_index;                        loghandle->lgh_cur_offset = (char *)rec - (char *)buf +                                last_offset;                        /* if set, process the callback on this record */                        if (ext2_test_bit(index, llh->llh_bitmap)) {                                rc = cb(loghandle, rec, data);                                last_called_index = index;                                if (rc == LLOG_PROC_BREAK) {                                        CDEBUG(D_HA, "recovery from log: "LPX64                                               ":%x stopped\n",                                               loghandle->lgh_id.lgl_oid,                                               loghandle->lgh_id.lgl_ogen);                                        GOTO(out, rc);                                } else if (rc == LLOG_DEL_RECORD) {                                        llog_cancel_rec(loghandle, rec->lrh_index);                                        rc = 0;                                }                                if (rc)                                        GOTO(out, rc);                        } else {                                CDEBUG(D_OTHER, "Skipped index %d\n", index);                        }                        /* next record, still in buffer? */                        ++index;                        if (index > last_index)                                GOTO(out, rc = 0);                }        } out:        if (cd != NULL)                cd->last_idx = last_called_index;        if (buf)                OBD_FREE(buf, LLOG_CHUNK_SIZE);        RETURN(rc);}EXPORT_SYMBOL(llog_process);inline int llog_get_size(struct llog_handle *loghandle){        if (loghandle && loghandle->lgh_hdr)                return loghandle->lgh_hdr->llh_count;        return 0;}EXPORT_SYMBOL(llog_get_size);int llog_reverse_process(struct llog_handle *loghandle, llog_cb_t cb,                         void *data, void *catdata){        struct llog_log_hdr *llh = loghandle->lgh_hdr;        struct llog_process_cat_data *cd = catdata;        void *buf;        int rc = 0, first_index = 1, index, idx;        ENTRY;        OBD_ALLOC(buf, LLOG_CHUNK_SIZE);        if (!buf)                RETURN(-ENOMEM);        if (cd != NULL)                first_index = cd->first_idx + 1;        if (cd != NULL && cd->last_idx)                index = cd->last_idx;        else                index = LLOG_BITMAP_BYTES * 8 - 1;        while (rc == 0) {                struct llog_rec_hdr *rec;                struct llog_rec_tail *tail;                /* skip records not set in bitmap */                while (index >= first_index &&                       !ext2_test_bit(index, llh->llh_bitmap))                        --index;                LASSERT(index >= first_index - 1);                if (index == first_index - 1)                        break;                /* get the buf with our target record; avoid old garbage */                memset(buf, 0, LLOG_CHUNK_SIZE);                rc = llog_prev_block(loghandle, index, buf, LLOG_CHUNK_SIZE);                if (rc)                        GOTO(out, rc);                rec = buf;                idx = le32_to_cpu(rec->lrh_index);                if (idx < index)                        CDEBUG(D_RPCTRACE, "index %u : idx %u\n", index, idx);                while (idx < index) {                        rec = ((void *)rec + le32_to_cpu(rec->lrh_len));                        idx ++;                }                tail = (void *)rec + le32_to_cpu(rec->lrh_len) - sizeof(*tail);                /* process records in buffer, starting where we found one */                while ((void *)tail > buf) {                        rec = (void *)tail - le32_to_cpu(tail->lrt_len) +                                sizeof(*tail);                        if (rec->lrh_index == 0)                                GOTO(out, 0); /* no more records */                        /* if set, process the callback on this record */                        if (ext2_test_bit(index, llh->llh_bitmap)) {                                rc = cb(loghandle, rec, data);                                if (rc == LLOG_PROC_BREAK) {                                        CWARN("recovery from log: "LPX64":%x"                                              " stopped\n",                                              loghandle->lgh_id.lgl_oid,                                              loghandle->lgh_id.lgl_ogen);                                        GOTO(out, rc);                                }                                if (rc)                                        GOTO(out, rc);                        }                        /* previous record, still in buffer? */                        --index;                        if (index < first_index)                                GOTO(out, rc = 0);                        tail = (void *)rec - sizeof(*tail);                }        }out:        if (buf)                OBD_FREE(buf, LLOG_CHUNK_SIZE);        RETURN(rc);}EXPORT_SYMBOL(llog_reverse_process);

⌨️ 快捷键说明

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