⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 log_read.c

📁 在Linux内核从2.4升级到2.6时需要升级的软件包
💻 C
📖 第 1 页 / 共 2 页
字号:
	return (nextrep);}/* * NAME:        setLogpage(pno, eor, pmax, buf) * * FUNCTION:    Forms consistent log page and returns eor and pmax values. * *              During the first release the following conditions are *              assumed: *              1) No corrupted write during power failure *              2) No split write *              3) No out-of-order sector write * *              If the header and trailer in the page are not equal, a *              system crash happened during this page write. It *              is reconciled as follows: * *              1) if h.page != t.page, the smaller value is taken and *                 the eor fields set to LOGPHDSIZE. *                 reason: This can happen when a old page is over-written *                 by a new page and the system crashed. So this page *                 should be considered not written. *              2) if h.eor != t.eor, the smaller value is taken. *                 reason: The last log page was rewritten for each *                 commit record. A system crash happened during the *                 page rewriting. Since we assume that no corrupted write *                 no split write and out-of-order sector write, the *                 previous successfuly writing is still good *              3) if no record ends on the page (eor = 8), still return it. *                 Let the caller determine whether a) a good long log record *                 ends on the next log page. or b) it is the first page of the *                 last long log record and system was crashed when its second *                 page is written. * * * RETURNS:     0                       - ok *              REFORMAT_ERROR(-3)      - I/O error, reformat log *              MAJOR_ERROR(-2)         - other major error */int setLogpage(int32_t pno,	/* page number of log           */	       int32_t *eor,	/* log header eor to return     */	       int32_t *pmax,	/* log header page number to return */	       int32_t buf){				/* logp[] index number for page */	int rc;	int32_t diff1, diff2;	/* check that header and trailer are the same */	if ((diff1 = (__le32_to_cpu(logp[buf].h.page) - __le32_to_cpu(logp[buf].t.page))) != 0) {		if (diff1 > 0)			/* Both little-endian */			logp[buf].h.page = logp[buf].t.page;		else			/* Both little-endian */			logp[buf].t.page = logp[buf].h.page;		logp[buf].h.eor = logp[buf].t.eor = __cpu_to_le16(LOGPHDRSIZE);		/* empty page */	}	if ((diff2 = (__le16_to_cpu(logp[buf].h.eor) - __le16_to_cpu(logp[buf].t.eor))) != 0) {		if (diff2 > 0)			/* Both little-endian */			logp[buf].h.eor = logp[buf].t.eor;		else			/* Both little-endian */			logp[buf].t.eor = logp[buf].h.eor;	}	/* if any difference write the page out */	if (diff1 || diff2) {		rc = ujfs_rw_diskblocks(Log.fp,					(uint64_t) (Log.xaddr + LOGPNTOB(pno)),					(unsigned long) LOGPSIZE, (char *) &logp[buf], PUT);		if (rc != 0) {			fsck_send_msg(lrdo_SLPWRITEFAIL, pno, rc);			return (JLOG_WRITEERROR1);		}	}	/*	 * At this point, it is still possible that logp[buf].h.eor	 * is LOGPHDRSIZE, but we return it anyway. The caller will make	 * decision.	 */	*eor = __le16_to_cpu(logp[buf].h.eor);	*pmax = __le32_to_cpu(logp[buf].h.page);	return (0);} /*    * NAME:        logRead(logaddr , ld, dataptr)    *    * FUNCTION:    reads the log record addressed by logaddr and    *              returns the address of the preceding log record.    *    * PARAMETERS:  logaddr -  address of the end of log record to read    *                                 Note: log is read backward, so this is    *                                 the address starting to read    *              ld      - pointer to a log record descriptor    *              dataptr - pointer to data buffer    *    * RETURNS:     < 0     - there is an i/o error in reading    *              > 0     - the address of the end of the preceding log record  */int logRead(int32_t logaddr,	/* address of log record to read */	    struct lrd *ld,	/* pointer to a log record descriptor */	    char *dataptr){				/* pointer to buffer.  LOGPSIZE*2 long */	int buf, off, rc, nwords, pno;	/* get page containing logaddr into log buffer pool */	pno = BTOLOGPN(logaddr);	if (pno != loglastp) {		loglastp = pno;		lognumread += 1;		if (lognumread > Log.size - 2) {			logError(LOGWRAP, 0);			fsck_send_msg(lrdo_LRLOGWRAP, lognumread);			return (JLOG_LOGWRAP);		}	}	buf = getLogpage(pno);	if (buf < 0) {		fsck_send_msg(lrdo_LRREADFAIL, pno, buf);		return (buf);	}	/* read the descriptor */	off = logaddr & (LOGPSIZE - 1);	/* offset just past desc. */	rc = moveWords(LOGRDSIZE / 4, (int32_t *) ld, &buf, &off);	if (rc < 0) {		fsck_send_msg(lrdo_LRMWFAIL1, rc);		return (rc);	}	ujfs_swap_lrd(ld);	/*	 * Legacy code used device number in ld->aggegate.  This code only	 * supported a single volume attached to the journal	 */	if (ld->aggregate > MAX_ACTIVE)		ld->aggregate = 0;	/* read the data if there is any */	if (ld->length > 0) {		if (ld->length > LOGPSIZE * 2) {			rc = READLOGERROR;			fsck_send_msg(lrdo_LRMWFAIL3, pno);			return (rc);		}		/* if length is partial word, still read it   */		nwords = (ld->length + 3) / 4;		rc = moveWords(nwords, (int32_t *) dataptr, &buf, &off);		if (rc < 0) {			fsck_send_msg(lrdo_LRMWFAIL2, rc);			return (rc);		}	}	return (LOGPNTOB(logptr[buf]) + off);}/* * NAME:        moveWords() * * FUNCTION:    moves nwords from buffer pool to target. data *              is moved in backwards direction starting at offset. *              If partial log record is on the previous page, *              or we have exhaust the current page (all bytes were read), *              the previous page is read into the buffer pool. *              On exit buf will point to this page in the buffer pool *              and offset to where the move stopped. * *              Note: the previous page is fetched whenever *              the current page is exhausted (all bytes were read) *              even if all the words required to satisfy this move *              are on the current page. * * PARAMETERS:  nwords  - number of 4-byte words to move *              target  - address of target (begin address) *              buf     - index in buffer pool of current page *              offset  - initial offset in buffer pool page, this offset *                        includes the page head size * * RETURNS:     = 0             - ok *              < 0             - error returned from getLogpage */int moveWords(int32_t nwords,	/* number of 4-byte words to move */		  int32_t *target,	/* address of target (begin address) */		  int32_t *buf,		/* index in buffer pool of curr page */		  int32_t *offset){				/* initial offset in buffer pool page */	int n, j, words, pno;	int *ptr;	j = (*offset - LOGPHDRSIZE) / 4 - 1;	/* index in log page data area						   of first word to move      */	words = min(nwords, j + 1);	/* words on this page to move */	ptr = target + nwords - 1;	/* last word of target */	for (n = 0; n < words; n++) {		*ptr = logp[*buf].data[j];		j = j - 1;		ptr = ptr - 1;	}	*offset = *offset - 4 * words;	/*	 * If partial log record is on the previous page,	 * or we have read all the log records in the current page,	 * get the previous page	 */	if (words != nwords	/* we get less than nwords */	    || j < 0) {		/* or exhaust the page, so offset is just */		/* the page head, then j < 0              */		/* get previous page */		pno = logptr[*buf];		pno = pno - 1;		/* if we hit beginning location of the log, go wrapped,		   read log record from the end location of the log   */		if (pno == 1)			pno = Log.size - 1;		*buf = getLogpage(pno);		if (*buf < 0) {			fsck_send_msg(lrdo_MWREADFAIL, pno, (*buf));			return (*buf);		}		*offset = LOGPSIZE - LOGPTLRSIZE;		/* index last word of data area */		j = LOGPSIZE / 4 - 4 - 1;		/* move rest of nwords if any. this will never		   exhaust the page.                          */		for (n = 0; n < nwords - words; n++) {			*ptr = logp[*buf].data[j];			j = j - 1;			ptr = ptr - 1;		}		*offset = *offset - 4 * (nwords - words);	}	return (0);}

⌨️ 快捷键说明

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