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

📄 logredo.c

📁 在Linux内核从2.4升级到2.6时需要升级的软件包
💻 C
📖 第 1 页 / 共 4 页
字号:
	 * store away the indicator of which aggregate superblock	 * to use	 */	use_2ndary_agg_superblock = use_2nd_aggSuper;	/*	 * loop until we get enough memory to read vmount struct	 */	mntinfo = (char *) &bufsize;	bufsize = sizeof (int);	/*	 * validate that the log is not currently in use;	 */	rc = findLog(fp, &in_use);	if (rc < 0) {		fsck_send_msg(lrdo_DEVOPNREADERROR);		return (rc);	}	/* recover from extendfs() ? */	if (Log.location & INLINELOG && (vopen[0].status & FM_EXTENDFS)) {		fsck_send_msg(lrdo_REXTNDBEGIN);		rc = recoverExtendFS(fp);		fsck_send_msg(lrdo_REXTNDDONE);		return rc;	}	/*	 * validate log superblock	 *	 * aggregate block size is for log file as well.	 */	rc = ujfs_rw_diskblocks(Log.fp,				(uint64_t) (Log.xaddr +					    LOGPNTOB(LOGSUPER_B)),				(unsigned) sizeof (struct logsuper), (char *) &logsup, GET);	if (rc != 0) {		fsck_send_msg(lrdo_CANTREADLOGSUP);		rc = LOGSUPER_READ_ERROR;		goto error_out;	}	ujfs_swap_logsuper(&logsup);	if (logsup.magic != LOGMAGIC) {		fsck_send_msg(lrdo_LOGSUPBADMGC);		rc = NOT_LOG_FILE_ERROR;		goto error_out;	}	if (logsup.version > LOGVERSION) {		fsck_send_msg(lrdo_LOGSUPBADVER);		rc = JFS_VERSION_ERROR;		goto error_out;	}	if (Log.location & OUTLINELOG) {		struct stat st;		if ((rc = fstat(fileno(Log.fp), &st)))			goto error_out;		Log.devnum = st.st_rdev;		if (in_use) {			fsck_send_msg(lrdo_LOGINUSE);			return LOG_IN_USE;		}	}	if (logsup.state == LOGREDONE) {		fsck_send_msg(lrdo_ALREADYREDONE);		if (Log.location & INLINELOG)			if ((rc = updateSuper(0)) != 0) {				fsck_send_msg(lrdo_CANTUPDLOGSUP);				return (rc);			}		return (0);	}	Log.size = logsup.size;	Log.serial = logsup.serial;	/*	 * find the end of log	 */	logend = findEndOfLog();	if (logend < 0) {		fsck_send_msg(lrdo_LOGEND, logend);		fsck_send_msg(lrdo_LOGENDBAD1);		logError(LOGEND, 0);		ujfs_swap_logsuper(&logsup);		rc = ujfs_rw_diskblocks(Log.fp,					(Log.xaddr + LOGPNTOB(LOGSUPER_B)),					(unsigned long) LOGPSIZE, (char *) &logsup, PUT);		rc = logend;		goto error_out;	}	/*	 * allocate/initialize logredo runtime data structures and	 * initialize each file system associated with the log based on	 * the contents of its superblock	 */	if ((rc = logredoInit()) != 0) {		fsck_send_msg(lrdo_INITFAILED, rc, errno);		goto error_out;	}	highest_lr_byte = logsup.size * LOGPSIZE - LOGRDSIZE;	if ((logend < lowest_lr_byte) || (logend > highest_lr_byte)) {		fsck_send_msg(lrdo_LOGEND, logend);		fsck_send_msg(lrdo_LOGENDBAD2);		rc = INVALID_LOGEND;		goto error_out;	}	/*	 *      replay log	 *	 * read log backwards and process records as we go.	 * reading stops at place specified by first SYNCPT we	 * encounter.	 */	nlogrecords = lastaddr = 0;	nextaddr = logend;	do {		logaddr = nextaddr;		nextaddr = logRead(logaddr, &ld, afterdata);		DBG_TRACE(("Logaddr=%x\nNextaddr=%x\n", logaddr, nextaddr))		    nlogrecords += 1;		/*		 *		 * Validate the nextaddr as much as possible		 *		 */		if (nextaddr < 0) {			fsck_send_msg(lrdo_NEXTADDRINVALID);			rc = nextaddr;			goto error_out;		}		if ((nextaddr < lowest_lr_byte)		    || (nextaddr > highest_lr_byte)) {			fsck_send_msg(lrdo_NEXTADDROUTRANGE, nextaddr);			rc = INVALID_NEXTADDR;			goto error_out;		}		if (nextaddr == logaddr) {			fsck_send_msg(lrdo_NEXTADDRSAME, nextaddr);			rc = NEXTADDR_SAME;			goto error_out;		}		if (nextaddr > logaddr) {			if (log_has_wrapped) {				fsck_send_msg(lrdo_LOGWRAPPED);				rc = LOG_WRAPPED_TWICE;				goto error_out;			} else {				log_has_wrapped = -1;			}		}		/*		 *		 * The addresses seem ok.  Process the current record.		 *		 */		switch (ld.type) {		case LOG_COMMIT:			rc = doCommit(&ld);			if (rc) {				fsck_send_msg(lrdo_BADCOMMIT, logaddr);				goto error_out;			}			break;		case LOG_MOUNT:			fsck_send_msg(lrdo_MOUNTRECORD, logaddr);			rc = doMount(&ld);			if (rc) {				fsck_send_msg(lrdo_BADMOUNT, logaddr);				goto error_out;			}			break;		case LOG_SYNCPT:			fsck_send_msg(lrdo_SYNCRECORD, logaddr);			rc = 0;			if (lastaddr == 0) {				syncrecord = logaddr;				lastaddr = (ld.log.syncpt.sync == 0)				    ? logaddr : ld.log.syncpt.sync;			}			break;		case LOG_REDOPAGE:			DBG_TRACE(("jfs_logredo:Case Log_redoPage"))			    rc = doAfter(&ld, logaddr);			if (rc) {				fsck_send_msg(lrdo_BADREDOPAGE, logaddr);				goto error_out;			}			break;		case LOG_NOREDOPAGE:			DBG_TRACE(("jfs_logredo:Case Log_noredopage"))			    rc = doNoRedoPage(&ld);			if (rc) {				fsck_send_msg(lrdo_BADNOREDOPAGE, logaddr);				goto error_out;			}			break;		case LOG_NOREDOINOEXT:			DBG_TRACE(("jfs_logredo:Case Log_noredoinoext"))			    rc = doNoRedoInoExt(&ld);			if (rc) {				fsck_send_msg(lrdo_BADNOREDOINOEXT, logaddr);				goto error_out;			}			break;		case LOG_UPDATEMAP:			rc = doUpdateMap(&ld);			if (rc) {				fsck_send_msg(lrdo_BADUPDATEMAP, logaddr);				goto error_out;			}			break;		default:			fsck_send_msg(lrdo_UNKNOWNTYPE, logaddr);			rc = UNRECOG_LOGRECTYP;			goto error_out;			break;		}		if (rc < 0) {			fsck_send_msg(lrdo_ERRORNEEDREFORMAT);			goto error_out;		}		if (rc != 0) {			fsck_send_msg(lrdo_ERRORCANTCONTIN);			goto error_out;		}		/*		 * If the transaction just completed was the last		 * for the current transaction, then flush the		 * buffers.		 */		if (end_of_transaction != 0) {			for (k = 1; k < NBUFPOOL; k++) {				if ((rc = bflush(k, &buffer[k - 1])) != 0)					goto error_out;			}			end_of_transaction = 0;		}	} while (logaddr != lastaddr);	/*	 * If any 'dtpage extend' records were processed, then we need	 * to go back and rebuild their freelists.  This cannot be done	 * when the 'dtpage extend' record is processed, since there may	 * be records processed later which affect the previous (shorter)	 * version of the dtpage.  Only after all these records are processed	 * can we safely and accurately rebuild the freelist.	 */	if (numExtDtPg != 0) {		rc = doExtDtPg();	}	/*	 * flush data page buffer cache	 */	for (k = 1; k < NBUFPOOL; k++) {		if ((rc = bflush(k, &buffer[k - 1])) != 0)			break;	}	/*	 *      finalize file systems	 *	 * update allocation map and superblock of file systems	 * of volumes which are open if they were modified here.	 * i.e. if they were not previously unmounted cleanly.	 */	for (k = 0; k < MAX_ACTIVE; k++) {		if (vopen[k].state != VOPEN_OPEN)			continue;		if ((rc = updateMaps(k)) != 0) {			fsck_send_msg(lrdo_ERRORCANTUPDMAPS);			goto error_out;		}		/* Make sure all changes are committed to disk before we		 * mark the superblock clean		 */		ujfs_flush_dev(vopen[k].fp);		if ((rc = updateSuper(k)) != 0) {			fsck_send_msg(lrdo_ERRORCANTUPDFSSUPER);			goto error_out;		}		/* sync superblock before journal is finalized */		ujfs_flush_dev(vopen[k].fp);	}	/*	 *      finalize log.	 *	 * clear active list.	 * If this is a fully replayed log then it can be moved to earlier	 * versions of the operating system.  Therefore switch the magic	 * number to the earliest level.	 */	if (logsup.state != LOGREADERR) {		for (k = 0; k < MAX_ACTIVE; k++)			uuid_clear(logsup.active[k]);		logsup.end = logend;		logsup.state = LOGREDONE;		logsup.magic = LOGMAGIC;	}	ujfs_swap_logsuper(&logsup);	rc = ujfs_rw_diskblocks(Log.fp, (Log.xaddr + LOGPNTOB(LOGSUPER_B)),				LOGPSIZE, (char *) &logsup, PUT);	/*	 * now log some info for the curious	 */	fsck_send_msg(lrdo_LOGEND, logend);	fsck_send_msg(lrdo_RPTSYNCNUM, syncrecord);	fsck_send_msg(lrdo_RPTSYNCADDR, lastaddr);	fsck_send_msg(lrdo_RPTNUMLOGREC, nlogrecords);	fsck_send_msg(lrdo_RPTNUMDOBLK, numdoblk);	fsck_send_msg(lrdo_RPTNUMNODOBLK, numnodofile);      error_out:	if (rc > 0) {		rc = rc * (-1);	}	/*	 * If everything went ok except that we didn't have	 * enough memory to deal with the block map, tell chkdsk	 * to be sure to do a full check and repair, but that a log	 * format is not necessary	 */	if ((rc == 0) && Insuff_memory_for_maps) {		rc = ENOMEM25;	}	return (rc);}/* * NAME:        doMount(ld) * * FUNCTION:    a log mount record is the first-in-time record which is *              put in the log so it is the last we want to process in *              logredo. so we mark volume as cleanly unmounted in vopen *              array. the mount record is imperative when the volume *              is a newly made filesystem. */int doMount(struct lrd *ld){				/* pointer to record descriptor */	int vol, status;	vol = ld->aggregate;	status = vopen[vol].status;	DBG_TRACE(("Logredo:domount: status=%d\n", status))	    if (!(status & (FM_LOGREDO | FM_DIRTY)))		vopen[vol].status = FM_CLEAN;	return (0);}/* * NAME:        openVol(vol) * * FUNCTION:    open the aggregate/volume specified. *              check if it was cleanly unmounted. also check log *              serial number. initialize disk and inode mpas. */int openVol(int vol){				/* device minor number of aggregate/lv */	int rc, l2agsize, agsize;	int64_t fssize;		/* number of aggr blks in the aggregate/lv */	struct superblock sb;	int aggsb_numpages;	if (Log.location & OUTLINELOG) {		/* First check if this is the already opened volume */		if (!uuid_compare(vopen[vol].uuid, primary_vol.uuid))			vopen[vol].fp = primary_vol.fp;		else {			vopen[vol].fp = open_by_label(vopen[vol].uuid, 0, 0,						      NULL, NULL);			if (vopen[vol].fp == NULL)				return ENOENT;		}	}	/* read superblock of the aggregate/volume */	if ((rc = rdwrSuper(vopen[vol].fp, &sb, PB_READ)) != 0) {		fsck_send_msg(lrdo_CANTREADFSSUPER);		fsError(READERR, vol, SUPER1_B);		vopen[vol].state = VOPEN_CLOSED;		return (FSSUPER_READERROR1);	}	/* check magic number and initialize version specific	 * values in the vopen struct for this vol.	 */	if (strncmp(sb.s_magic, JFS_MAGIC, (unsigned) strlen(JFS_MAGIC))) {		fsck_send_msg(lrdo_FSSUPERBADMAGIC);		vopen[vol].state = VOPEN_CLOSED;		return (LOGSUPER_BADMAGIC);	}	if (sb.s_version > JFS_VERSION) {		fsck_send_msg(lrdo_FSSUPERBADMAGIC);		vopen[vol].state = VOPEN_CLOSED;		return (LOGSUPER_BADVERSION);	}	if (Log.location & OUTLINELOG && (sb.s_flag & (JFS_INLINELOG == JFS_INLINELOG))) {		fsck_send_msg(lrdo_FSSUPERBADLOGLOC);		vopen[vol].state = VOPEN_CLOSED;		return (LOGSUPER_BADLOGLOC);	}	vopen[vol].lblksize = sb.s_bsize;	vopen[vol].l2bsize = sb.s_l2bsize;	vopen[vol].l2bfactor = sb.s_l2bfactor;	fssize = sb.s_size >> sb.s_l2bfactor;	vopen[vol].fssize = fssize;	vopen[vol].agsize = sb.s_agsize;	/* LOG2NUM will alter agsize, so use local var (Then why don't we	   fix LOG2NUM?) */	agsize = vopen[vol].agsize;	LOG2NUM(agsize, l2agsize);	vopen[vol].numag = fssize >> l2agsize;	if (fssize & (vopen[vol].agsize - 1))		vopen[vol].numag += 1;	vopen[vol].l2agsize = l2agsize;	if (Log.location & INLINELOG) {		/*		 * Now that the aggregate superblock has been read, do some		 * more validation of the log superblock		 */		if (logsup.bsize != vopen[vol].lblksize) {			fsck_send_msg(lrdo_LOGSUPBADBLKSZ);			return JFS_BLKSIZE_ERROR;		}		if (logsup.l2bsize != vopen[vol].l2bsize) {			fsck_send_msg(lrdo_LOGSUPBADL2BLKSZ);			return JFS_L2BLKSIZE_ERROR;		}

⌨️ 快捷键说明

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