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

📄 logredo.c

📁 在Linux内核从2.4升级到2.6时需要升级的软件包
💻 C
📖 第 1 页 / 共 4 页
字号:
		aggsb_numpages = lengthPXD(&sb.s_logpxd) * logsup.bsize / LOGPSIZE;		if (logsup.size != aggsb_numpages) {			fsck_send_msg(lrdo_LOGSUPBADLOGSZ);			return JFS_LOGSIZE_ERROR;		}	}	/*	 *set lbperpage in vopen.	 */	vopen[vol].lbperpage = PSIZE >> vopen[vol].l2bsize;	/*	 * was it cleanly umounted ?	 */	if (sb.s_state == FM_CLEAN) {		vopen[vol].status = FM_CLEAN;		vopen[vol].state = VOPEN_CLOSED;		return (0);	}	/*	 * get status of volume	 */	vopen[vol].status = sb.s_state;	vopen[vol].is_fsdirty = (sb.s_state & FM_DIRTY);	/*	 *check log serial number	 */	if (sb.s_logserial != Log.serial) {		fsck_send_msg(lrdo_FSSUPERBADLOGSER);		vopen[vol].state = VOPEN_CLOSED;		fsError(SERIALNO, vol, SUPER1_B);		return (LOGSUPER_BADSERIAL);	}	/* initialize the disk and inode maps	 */	if ((rc = initMaps(vol)) != 0) {		fsck_send_msg(lrdo_INITMAPSFAIL);		fsError(MAPERR, vol, 0);		return (rc);	}	vopen[vol].state = VOPEN_OPEN;	return 0;}/* * NAME:         updateSuper(vol) * * FUNCTION:     updates primary aggregate/lv's superblock status and *               writes it out. */int updateSuper(int vol){				/* device minor number of aggregate/lv */	int rc, status;	struct superblock sb;	/* read in superblock of the volume */	if ((rc = rdwrSuper(vopen[vol].fp, &sb, PB_READ)) != 0) {		fsck_send_msg(lrdo_READFSSUPERFAIL);		return (FSSUPER_READERROR2);	}	/* mark superblock state. write it out */	status = vopen[vol].status;	if (status & (FM_DIRTY | FM_LOGREDO))		sb.s_state = status & ~FM_EXTENDFS;	else		sb.s_state = FM_CLEAN;	if ((rc = rdwrSuper(vopen[vol].fp, &sb, PB_UPDATE)) != 0) {		fsck_send_msg(lrdo_WRITEFSSUPERFAIL);	}	return (rc);}/* * NAME:        rdwrSuper(fp, sb, rwflag) * * FUNCTION:    read or write the superblock for the file system described *              by the file descriptor of the opened aggregate/lv. *              for read, if a read of primary superblock is failed, *              try to read the secondary superblock. report error only *              when both reads failed. *              for write, any write failure should be reported. */int rdwrSuper(FILE *fp, struct superblock * sb, int32_t rwflag){	int rc;	uint64_t super_offset;	union {		struct superblock super;		char block[PSIZE];	} super;	if (use_2ndary_agg_superblock) {		super_offset = SUPER2_OFF;	} else {		super_offset = SUPER1_OFF;	}	/*	 * seek to the postion of the primary superblock.	 * since at this time we don't know the aggregate/lv	 * logical block size yet, we have to use the fixed	 * byte offset address super_offset to seek for.	 */	/*	 * read super block	 */	if (rwflag == PB_READ) {		rc = ujfs_rw_diskblocks(fp, super_offset,					(unsigned) SIZE_OF_SUPER, super.block, GET);		if (rc != 0) {			if (!use_2ndary_agg_superblock) {				fsck_send_msg(lrdo_READFSPRIMSBFAIL);				return (CANTREAD_PRIMFSSUPER);			} else {				fsck_send_msg(lrdo_READFS2NDSBFAIL);				return (CANTREAD_2NDFSSUPER);			}		}		*sb = super.super;		ujfs_swap_superblock(sb);		/*		 * write superblock		 */	} else {		/* PB_UPDATE */		/* ? memset(super.block, 0, SIZE_OF_SUPER); */		super.super = *sb;		ujfs_swap_superblock(&super.super);		/*		 * write whichever superblock we're working with.		 * chkdsk will take care of replicating it.		 */		rc = ujfs_rw_diskblocks(fp, super_offset,					(unsigned) SIZE_OF_SUPER, super.block, PUT);		if (rc != 0) {			if (!use_2ndary_agg_superblock) {				fsck_send_msg(lrdo_WRITEFSPRIMSBFAIL);				return (CANTWRITE_PRIMFSSUPER);			} else {				fsck_send_msg(lrdo_WRITEFS2NDSBFAIL);				return (CANTWRITE_2NDFSSUPER);			}		}	}	return (0);}/* * NAME:        bflush() * * FUNCTION:    write out appropriate portion of buffer page if its modified. *              Note that a dtree page may not be 4k, depending on the length *              field specified in pxd. Write out only length that is needed. */int bflush(int32_t k,		/*  The index in bufhdr that describes buf */	   struct bufpool *buf){				/* pointer to buffer pool page */	FILE *fp = NULL;	int rc;	int32_t vol;	int32_t nbytes;	int64_t blkno;	/* nothing to do ? */	if (bufhdr[k].modify == 0)		return (0);	/* write it out */	vol = bufhdr[k].vol;	fp = vopen[vol].fp;	blkno = addressPXD(&bufhdr[k].pxd);	nbytes = lengthPXD(&bufhdr[k].pxd) << vopen[vol].l2bsize;	rc = ujfs_rw_diskblocks(fp,				(uint64_t) (blkno << vopen[vol].l2bsize),				(unsigned) nbytes, (char *) buf, PUT);	if (rc != 0) {		fsck_send_msg(lrdo_BUFFLUSHFAIL);		return (BFLUSH_WRITEERROR);	}	bufhdr[k].modify = 0;	return (0);}/* * NAME:        findLog() * * FUNCTION:    open the device to see if it's a valid filesystem * 		or journal.  If it is a filesystem, determine whether * 		the log is inline or external.  If external, find * 		the log device. * */int findLog(FILE *fp, int *in_use){	struct logsuper logsup;	struct superblock sb;	*in_use = 0;	/*	 * try the LV as file system with in-line log	 */	if (rdwrSuper(fp, &sb, PB_READ)) {		fsck_send_msg(lrdo_NOTAFSDEV);		return NOT_FSDEV_ERROR;	}	/*	 * is the LV a file system ?	 */	if (memcmp(sb.s_magic, JFS_MAGIC, sizeof (sb.s_magic)) == 0) {		/*		 * does file system contains its in-line log ?		 */		if ((sb.s_flag & JFS_INLINELOG) == JFS_INLINELOG) {			Log.location = INLINELOG;			Log.fp = fp;			//Log.status = sb.s_state;			Log.l2bsize = sb.s_l2bsize;			Log.xaddr = addressPXD(&sb.s_logpxd) << sb.s_l2bsize;			/* vopen[0] represents fs if inline log */			vopen[0].status = sb.s_state;			vopen[0].fp = fp;			return 0;		}		/* Save fp and uuid */		primary_vol.fp = fp;		uuid_copy(primary_vol.uuid, sb.s_uuid);		/*		 * External log		 *		 * First check device specified on		 * command line		 */		Log.xaddr = 0;		if (log_device[0]) {			Log.fp = NULL;			if (LogOpenMode != O_RDONLY) {				Log.fp = fopen_excl(log_device, "r+");				if (Log.fp == NULL)					*in_use = 1;			}			if (Log.fp == NULL) {				Log.fp = fopen(log_device, "r");				if (Log.fp == NULL) {					printf("Invalid journal specified (%s)\n",					       log_device);					goto by_uuid;				}			}			ujfs_rw_diskblocks(Log.fp, LOGPNTOB(LOGSUPER_B),					   sizeof (struct logsuper), &logsup, GET);			ujfs_swap_logsuper(&logsup);			if ((logsup.magic != LOGMAGIC) || (uuid_compare(logsup.uuid, sb.s_loguuid))) {				fclose(Log.fp);				*in_use = 0;				goto by_uuid;			}			Log.location = OUTLINELOG;			return 0;		}	      by_uuid:		Log.fp = open_by_label(sb.s_loguuid, 0, 1, NULL, in_use);		if (Log.fp != NULL) {			Log.location |= OUTLINELOG;			return 0;		}		return NOT_INLINELOG_ERROR;	}	/*	 * is this an external log?	 */	ujfs_rw_diskblocks(fp, LOGPNTOB(LOGSUPER_B), sizeof (struct logsuper), &logsup, GET);	ujfs_swap_logsuper(&logsup);	if (logsup.magic != LOGMAGIC) {		fsck_send_msg(lrdo_NOTAFSDEV);		return NOT_FSDEV_ERROR;	}	Log.fp = fp;	Log.location = OUTLINELOG;	return 0;}extern void exit(int);/* * NAME:        fsError(type,vol,bn) * * FUNCTION:    error handling code for the specified *              aggregate/lv (filesystem). */int fsError(int type,		/* error types */	    int vol,		/* the minor number of the aggregate/lv */	    int64_t bn){				/* aggregate block No.  */	fsck_send_msg(lrdo_ERRORONVOL, vol);	retcode = -1;	vopen[vol].status = FM_LOGREDO;	switch (type) {	case OPENERR:		fsck_send_msg(lrdo_OPENFAILED);		break;	case MAPERR:		fsck_send_msg(lrdo_CANTINITMAPS);		break;	case DBTYPE:		fsck_send_msg(lrdo_BADDISKBLKNUM, (long long) bn);		break;	case INOTYPE:		fsck_send_msg(lrdo_BADINODENUM, (long long) bn);		break;	case READERR:		fsck_send_msg(lrdo_CANTREADBLK, (long long) bn);		break;	case SERIALNO:		fsck_send_msg(lrdo_BADLOGSER);		break;	case IOERROR:		fsck_send_msg(lrdo_IOERRREADINGBLK, (long long) bn);		break;	case LOGRCERR:		fsck_send_msg(lrdo_BADUPDMAPREC, (long long) bn);		break;	}	return (0);}/* *      logError(type) * * error handling for log read errors. */int logError(int type, int logaddr){	int k;	retcode = -1;	logsup.state = LOGREADERR;	switch (type) {	case LOGEND:		fsck_send_msg(lrdo_FINDLOGENDFAIL);		break;	case READERR:		fsck_send_msg(lrdo_LOGREADFAIL, logaddr);		break;	case UNKNOWNR:		fsck_send_msg(lrdo_UNRECOGTYPE, logaddr);		break;	case IOERROR:		fsck_send_msg(lrdo_IOERRONLOG, logaddr);		break;	case LOGWRAP:		fsck_send_msg(lrdo_LOGWRAP);	}	/* mark all open volumes in error	 */	for (k = 0; k < MAX_ACTIVE; k++) {		if ((vopen[k].state == VOPEN_OPEN) && vopen[k].status != FM_CLEAN)			vopen[k].status = FM_LOGREDO;	}	return (0);}/* *	recoverExtendFS() * * function: recover crash while in extendfs() for inline log; * * note: fs superblock fields remains pre-extendfs state, * while that bmap file, fsck and inline log area may be in * unknown state; * * at entry, only log type/lv has been validated; * for inline log: vopen[0], fs fp = log fp; */static int recoverExtendFS(FILE *fp){	struct superblock *sbp;	struct dinode *dip1, *dip2;	struct dbmap *bgcp;	xtpage_t *p;	int64_t lmchild = 0, xaddr, xoff, barrier, t64, agsize;	uint8_t lmxflag;	int32_t i;	char *dip, *bp;	pxd_t temp_pxd;	/*	 * read bmap global control page	 */	/* read superblock yet again */	sbp = (struct superblock *) &buffer[0];	if (rdwrSuper(fp, sbp, PB_READ))		goto errout;	/* read primary block allocation map inode */	dip = (char *) &buffer[1];	if (ujfs_rw_diskblocks(fp, AITBL_OFF, PSIZE, dip, GET)) {		fsck_send_msg(lrdo_EXTFSREADFSSUPERFAIL);		goto errout;	}	/* locate the inode in the buffer page */	dip1 = (struct dinode *) dip;	dip1 += BMAP_I;	bp = (char *) &buffer[2];	/* utility buffer */	/* start from root in dinode */	p = (xtpage_t *) & dip1->di_btroot;	/* is this page leaf ? */	if (p->header.flag & BT_LEAF)		goto rdbgcp;	/* traverse down leftmost child node to leftmost leaf of xtree */	do {		/* read in the leftmost child page */		t64 = addressXAD(&p->xad[XTENTRYSTART]) << sbp->s_l2bsize;		if (ujfs_rw_diskblocks(fp, t64, PSIZE, bp, GET)) {			fsck_send_msg(lrdo_EXTFSREADBLKMAPINOFAIL);			goto errout;		}		p = (xtpage_t *) bp;		/* is this page leaf ? */		if (p->header.flag & BT_LEAF)			break;	} while (1);      rdbgcp:	t64 = addressXAD(&p->xad[XTENTRYSTART]) << sbp->s_l2bsize;	if (ujfs_rw_diskblocks(fp, t64, PSIZE, bp, GET)) {		fsck_send_msg(lrdo_EXTFSREADBLKFAIL1, (long long) t64);		goto errout;	}	bgcp = (struct dbmap *) bp;	/*	 * recover to pre- or post-extendfs state ?:	 */	if (__le64_to_cpu(bgcp->dn_mapsize) > (sbp->s_size >> sbp->s_l2bfactor)) {		agsize = __le64_to_cpu(bgcp->dn_agsize);		goto postx;	}	/*	 *    recover pre-extendfs state	 */	/*	 * reset block allocation map inode (xtree root)	 */	/* read 2ndary block allocation map inode */	t64 = addressPXD(&sbp->s_ait2) << sbp->s_l2bsize;	if (ujfs_rw_diskblocks(fp, t64, PSIZE, bp, GET)) {		fsck_send_msg(lrdo_EXTFSREADBLKFAIL2, (long long) t64);		goto errout;	}	dip2 = (struct dinode *) bp;	dip2 += BMAP_I;	/*	 * Reset primary bam inode with 2ndary bam inode

⌨️ 快捷键说明

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