📄 log_read.c
字号:
/* * Copyright (c) International Business Machines Corp., 2000-2002 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <config.h>#include <time.h>#include <stdio.h>#include <stdlib.h>#include <memory.h>#include <string.h>#include <errno.h>#include "jfs_types.h"#include "jfs_endian.h"#include "jfs_filsys.h"#include "jfs_superblock.h"#include "jfs_dinode.h"#include "jfs_dtree.h"#include "jfs_xtree.h"#include "jfs_logmgr.h"#include "jfs_dmap.h"#include "jfs_imap.h"#include "logredo.h"#include "devices.h"#include "debug.h"#include "fsck_message.h" /* for fsck message logging facility */ /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * * R E M E M B E R M E M O R Y A L L O C F A I L U R E * */extern int32_t Insuff_memory_for_maps;extern char *available_stg_addr;extern int32_t available_stg_bytes;extern char *bmap_stg_addr;extern int32_t bmap_stg_bytes; /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * * L O C A L M A C R O D E F I N I T I O N S * */#define BTOLOGPN(x) ((unsigned)(x) >> L2LOGPSIZE)#define LOGPNTOB(x) ((x)<<L2LOGPSIZE)#define min(A,B) ((A) < (B) ? (A) : (B)) /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * * S T U F F F O R T H E L O G * * externals defined in logredo.c */int32_t loglastp; /* last page of log read */int32_t lognumread; /* number of log pages read *//* * open file system aggregate/lv array * Defined in logredo.c */extern struct vopen vopen[]; /* (88) *//* * log page buffer cache * * log has its own 4 page buffer pool. * externals defined in logredo.c */int nextrep; /* next log buffer pool slot to replace */int logptr[4]; /* log pages currently held in logp */struct logpage logp[4]; /* log page buffer pool *//* * external references */extern int logError(int, int);/* * forward references */int findEndOfLog(void);int pageVal(int, int *, int *);int getLogpage(int);int setLogpage(int32_t pno, int32_t *, int32_t *, int32_t);int logRead(int32_t, struct lrd *, char *);int moveWords(int32_t, int32_t *, int32_t *, int32_t *);/* * NAME: findEndOfLog() * * FUNCTION: Returns the address of the end of the last record in the log. * (i.e. the address of the byte following its descriptor). * * Note: At the first release, log page is not written in a ping pong * manner, so the logend is the binary search result * * The end of the log is found by finding the page with the * highest page number and for which h.eor == t.eor and * h.eor > 8 (i.e. a record ends on the page). * Page numbers are compared by comparing their difference * with zero (necessary because page numbers are allowed to wrap.) * * RETURNS: >0 - byte offset of last record * REFORMAT_ERROR(-3) - i/o error, reformat the log * MAJOR_ERROR(-2) - other major errors other than EIO. */int findEndOfLog(){ int rc; int32_t left, right, pmax, pval, eormax, eorval, k; /* binary search for logend */ left = 2; /* first page containing log records since page 0 is never used, page 1 is log superblock */ right = Log.size - 1; /* last page containing log records */ if ((rc = pageVal(left, &eormax, &pmax)) < 0) { fsck_send_msg(lrdo_FEOLPGV1FAIL, rc); return (rc); } while ((right - left) > 1) { k = (left + right) >> 1; if ((rc = pageVal(k, &eorval, &pval)) < 0) { fsck_send_msg(lrdo_FEOLPGV2FAIL, rc); return (rc); } if (pval - pmax > 0) { left = k; pmax = pval; eormax = eorval; } else right = k; } if ((rc = pageVal(right, &eorval, &pval)) < 0) { fsck_send_msg(lrdo_FEOLPGV3FAIL, rc); return (rc); } /* * the last thing to determine is whether it is the first page of * the last long log record and system was crashed when its second * page is written. If the eor of the chosen page is LOGPHDRSIZE, * then this page contains a partial log record, ( otherwise, the * the long log record's second page should be chosen ). * This page should be thrown away. its previous page will be * the real last log page. */ if ((pval - pmax) > 0) { if (eorval == LOGPHDRSIZE) { if ((rc = pageVal(right - 1, &eorval, &pval)) < 0) { fsck_send_msg(lrdo_FEOLPGV4FAIL, rc); return (rc); } return (LOGPNTOB(right - 1) + eorval); } else return (LOGPNTOB(right) + eorval); } else { if (eormax == LOGPHDRSIZE) { left = (left == 2) ? Log.size - 1 : left - 1; if ((rc = pageVal(left, &eormax, &pmax)) < 0) { fsck_send_msg(lrdo_FEOLPGV4AFAIL, rc); return (rc); } } return (LOGPNTOB(left) + eormax); }}/* * NAME: pageVal(pno, eor, pmax) * * FUNCTION: Read the page into the log buffer pool and call setLogpage * to form consistent log page. * * RETURNS: 0 - ok * REFORMAT_ERROR(-3) - I/O error, reformat the log * MAJOR_ERROR(-2) - other major errors other than EIO. */int pageVal(int pno, /* page number in log */ int *eor, /* corresponding eor value */ int *pmax){ /* pointer to returned page number */ int buf0; /* logp[] buffer element number */ /* Read the page into the log buffer pool. */ if ((buf0 = getLogpage(pno)) < 0) { fsck_send_msg(lrdo_PVGETPGFAIL, pno, buf0); return (buf0); } return (setLogpage(pno, eor, pmax, buf0));}/* * NAME: getLogpage(pno) * * FUNCTION: if the specified log page is in buffer pool, return its * index. Otherwise read log page into buffer pool. * * PARAMETERS: pno - log page number to look for. * * RETURNS: 0 - 3 - index of the buffer pool the page located * REFORMAT_ERROR(-3) - I/O error, reformat the log * MAJOR_ERROR(-2) - other major errors other than EIO. */int getLogpage(int pno){ /* page of log */ int k, rc; /* * is it in buffer pool ? */ for (k = 0; k <= 3; k++) if (logptr[k] == pno) return (k); /* * read page into buffer pool into next slot * don't have to use llseek() here. log dev will never be > 2 gig */ nextrep = (nextrep + 1) % 4; if (Log.location & INLINELOG) rc = ujfs_rw_diskblocks(Log.fp, (uint64_t) (Log.xaddr + LOGPNTOB(pno)), (unsigned) LOGPSIZE, (char *) &logp[nextrep], GET); else rc = ujfs_rw_diskblocks(Log.fp, (uint64_t) LOGPNTOB(pno), (unsigned) LOGPSIZE, (char *) &logp[nextrep], GET); if (rc != 0) { return (JLOG_READERROR1); } logptr[nextrep] = pno;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -