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

📄 log_work.c

📁 在Linux内核从2.4升级到2.6时需要升级的软件包
💻 C
📖 第 1 页 / 共 5 页
字号:
 * * FUNCTION:    Processing for LOG_NOREDOPAGE rec type. * *              This routine starts a NoRedoPage filter for the *              specified xtree or dtree node (may be root). * *              This routine updates the bmap when the freed node *              is NOT the root node. *              (ld->log.noredopage.pxd = old page extent) * * NOTE:        This routine only updates the block map when the *              extent being freed describes a dtree page. *              Block map updates for a freed xtree page are handled *              when the UPDATEMAP log record is seen. * */int doNoRedoPage(struct lrd *ld){				/* pointer to log record descriptor */	int vol, rc = 0;	int32_t hash;	struct nodofile *nodoptr;	pxd_t pxd1;	struct doblk *db;	int32_t inonum;	uint8_t mask_8;	/*	 * If it's not part of a committed transaction then it	 * should be ignored, so just return.	 */	if (!findCommit(ld->logtid))		return (0);	/*	 * if it's the last entry for the current committed transaction,	 * remove the commit record from the commit list because we won't	 * be needing it any more.	 */	if (ld->backchain == 0)		deleteCommit(ld->logtid);	/*	 * if the filesystem was cleanly unmounted or if the last	 * thing that happened was a logredo failure, skip  this	 * record.  (Necessary for the case of logredo a log shared	 * by multiple filesystems.  We want to process log records	 * for those filesystems which don't meet this criteria, but	 * skip log records for those which do.)	 */	vol = ld->aggregate;	if (vopen[vol].status == FM_CLEAN || vopen[vol].status == FM_LOGREDO)		return (0);	/*	 * We may already have a NoRedoPage filter in effect.	 * If one is found on the NoRedoFile hash chain, goto update	 * map.	 *	 * N.B.  The log.noredopage.inode in the log record is the	 *       inode number of the applicable imap.  We NEVER	 *       NoRedoFile for an imap inode.	 */	hash = (ld->aggregate + ld->log.noredopage.inode) & nodofilehmask;	for (nodoptr = nodofilehash[hash]; nodoptr != NULL;	     nodoptr = nodoptr->next) {		if (ld->aggregate == nodoptr->aggregate &&		    ld->log.noredopage.inode == nodoptr->inode)			goto updmap;	}	/*	 * start NoRedoPage filter for LOG_NOREDOPAGE log rec.	 *	 */	pxd1 = ld->log.noredopage.pxd;	/*	 * DTREE ROOT	 *	 * Do not process any further log records for	 * the root of the specified (directory) inode's dtree.	 */	if ((ld->log.noredopage.type & (LOG_BTROOT | LOG_DTREE))	    == (LOG_BTROOT | LOG_DTREE)) {		/*		 * get the noredopage record for this page		 * (one is created if none exists)		 */		rc = findPageRedo(ld->aggregate, pxd1, &db);		if (rc != 0) {			fsck_send_msg(lrdo_DNRPFNDDTRTPGREDOFAIL, rc);			return (rc);		}		/*		 * mark the appropriate slot in the noredopage for		 * no further updates to this (directory) inode's		 * dtree root.		 */		inonum = ld->log.redopage.inode & 0x07;		db->db_dtroot[inonum] = 0x01ff;		/*		 * This inode is identified as a dtroot.  So mark		 * the appropriate slot in the noredopage for		 * NO updates to this inode as an xtroot.		 */		mask_8 = UZBIT_8 >> inonum;		db->db_xtrt_lwm[inonum] = XTENTRYSTART;		db->db_xtrt_hd |= mask_8;		/*		 * XTREE ROOT		 *		 * Do not process any further log records for		 * the root of the specified inode's xtree.		 */	} else if ((ld->log.redopage.type & (LOG_BTROOT | LOG_XTREE))		   == (LOG_BTROOT | LOG_XTREE)) {		/*		 * get the noredopage record for this page		 * (one is created if none exists)		 */		rc = findPageRedo(ld->aggregate, pxd1, &db);		if (rc != 0) {			fsck_send_msg(lrdo_DNRPFNDXTRTPGREDOFAIL, rc);			return (rc);		}		/*		 * mark the appropriate slot in the noredopage for no		 * further updates to this inode's xtree root.		 */		inonum = ld->log.redopage.inode & 0x07;		mask_8 = UZBIT_8 >> inonum;		db->db_xtrt_lwm[inonum] = XTENTRYSTART;		db->db_xtrt_hd |= mask_8;		/*		   * This inode is identified as an xtree root.  So		   * mark the appropriate slot in the noredopage for		   * NO updates to this inode's root as a dtree.		 */		db->db_dtroot[inonum] = 0x01ff;		/*		 * DTREE, XTREE, or DATA NODE		 *		 * Do not process any further log records for		 * the specified page.		 */	} else if (ld->log.redopage.type & (LOG_XTREE | LOG_DTREE | LOG_DATA)) {		/*		 * get the noredopage record for this page		 * (one is created if none exists)		 */		rc = findPageRedo(ld->aggregate, pxd1, &db);		if (rc != 0) {			fsck_send_msg(lrdo_DNRPFNDXTPGPGREDOFAIL, rc);			return (rc);		}		db->type = LOG_NONE;		/*		 * UNRECOGNIZED TYPE		 *		 * We don't ever expect to get here!		 */	} else {		fsck_send_msg(lrdo_DNRPUNKNOWNTYPE);	}	/*	 * If this is a (non-root) dtree page update the bmap.	 */      updmap:	if (ld->log.noredopage.type == LOG_DTREE) {		rc = markBmap((struct dmap *) vopen[vol].bmap_ctl, ld->log.noredopage.pxd, 0, vol);		if (rc != 0) {			return (rc);		}	}	return (0);}/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * * NAME:        doNoRedoInoExt() * * FUNCTION:    Processing for LOG_NOREDOINOEXT rec type. * *              This routine starts a NoRedoPage filter for each *		page in the inode extent being released. * *              This routine may updates the bmap and the imap. * * NOTE:        The noredoinoext.pxd describes a 4 (4096-byte) page *		inode extent. * * * NOTE:	This log record was written when an inode extent was *		released. * *		At this point, there are 3 possibilities: * *		o the extent could have been reallocated for an inode *		  extent (possibly even for the same inode number range. *		  If this is true, then there is already a NoRedoExtent *		  filter in effect. * *		o the extent could now be allocated for user data or for *		  JFS metadata.  If this is true, then further updates *		  to the blocks in the extent would violate data *		  integrity.  Therefore, we establish a NoRedoExtent *		  filter (i.e., a NoRedoPage filter for each of the *		  4 pages in the extent). * *		o the extent could be unallocated.  That is, none of the *		  blocks in the extent pages are in use.  If this is *		  true, then further updates to the blocks in the extent *		  are a waste of processing time.  Therefore, we establish *		  a NoRedoExtent filter (i.e., a NoRedoPage filter for *		  each of the 4 pages in the extent). * */int doNoRedoInoExt(struct lrd *ld){				/* pointer to log record descriptor */	int pg_idx, vol, rc = 0;	pxd_t pxd1;	struct doblk *db;	int32_t iagnum, iagext_idx;	struct iag_data *imp;	/*	 * If it's not part of a committed transaction then it	 * should be ignored, so just return.	 */	if (!findCommit(ld->logtid))		return (0);	/*	 * if it's the last entry for the current committed transaction,	 * remove the commit record from the commit list because we won't	 * be needing it any more.	 */	if (ld->backchain == 0)		deleteCommit(ld->logtid);	/*	 * if the filesystem was cleanly unmounted or if the last	 * thing that happened was a logredo failure, skip  this	 * record.  (Necessary for the case of logredo a log shared	 * by multiple filesystems.  We want to process log records	 * for those filesystems which don't meet this criteria, but	 * skip log records for those which do.)	 */	vol = ld->aggregate;	if (vopen[vol].status == FM_CLEAN || vopen[vol].status == FM_LOGREDO)		return (0);	/*	 * Establish the 4 NoRedoPage filters which together	 * form the NoRedoExtent filter.	 */	pxd1 = ld->log.noredoinoext.pxd;	for (pg_idx = 0; pg_idx < 4; pg_idx++) {		/*		 * find the noredo record for this page.		 * (or create one if not found)		 */		rc = findPageRedo(ld->aggregate, pxd1, &db);		if (rc != 0) {			fsck_send_msg(lrdo_DNRIFNDNOREDORECFAIL, rc);			return (rc);		}		/*		 * mark for no inode updates to the page, no matter what		 * format it might appear to have		 */		db->type = LOG_NONE;		/*		 * set up for the next page in the extent		 */		PXDaddress(&pxd1, (addressPXD(&pxd1) + vopen[vol].lbperpage)		    );	}			/* end for */	/*	 * Now go update the block map if appropriate.	 *	 * Note:	 *    If any of these blocks has been allocated LATER	 *  (in time) than this extent release then we don't	 *  want to mark them unallocated, but if not then	 *  we must mark them unallocated.  Since we process	 *  log records in LIFO order, we have already	 *  processed the log record(s) (if any) describing	 *  reallocation of the block(s).	 *	 *  The markBmap routine only marks the block map	 *  for blocks whose status has not already been	 *  set by markBmap in the current logredo session.	 *	 */	rc = markBmap((struct dmap *) vopen[vol].bmap_ctl, ld->log.noredoinoext.pxd, 0, vol);	if (rc != 0) {		return (rc);	}	/*	 * Now, if no extent has been reallocated for	 * the inodes in the range which the extent being	 * released describes, then the IAG needs to be	 * updated to show that this extent is not	 * allocated.	 *	 * NOTE: It is not necessary to adjust the IAG	 *       Free Extent List, the IAG Free Inodes List,	 *       or the Free IAG List because they will be	 *       rebuilt from scratch before the filesystem	 *       is remounted (either near the end of logredo	 *         processing or by fsck after logredo returns	 *       control to it with rc != 0)	 *	 * NOTE: The wmap of the IAG tells whether logredo	 *       has already encountered a log record for	 *       one of these inodes.  This would mean	 *       activity for the inode(s) LATER IN TIME	 *       than the current transaction.  If no such	 *         record has been seen, then the IAG[extno]	 *       needs to be cleared.	 */	iagnum = ld->log.noredoinoext.iagnum;	imp = vopen[vol].fsimap_lst.imap_wsp[(iagnum + 1)].imap_data;	if (imp == NULL) {	/* first touch to this IAG */		rc = iagGet(vol, iagnum);		if (rc != 0) {			return (rc);		}		imp = vopen[vol].fsimap_lst.imap_wsp[(iagnum + 1)].imap_data;	}	/* end first touch to this IAG */	iagext_idx = ld->log.noredoinoext.inoext_idx;	if (imp->wmap[iagext_idx] == 0) {		/* no later activity for		 * the inodes in the range for this		 * inode extent.		 */		/* all of them are now in a determined state */		imp->wmap[iagext_idx] = 0xFFFFFFFF;		/* and that state is 'not allocated' */		imp->pmap[iagext_idx] = 0x00000000;		PXDlength(&(imp->inoext[iagext_idx]), 0);		PXDaddress(&(imp->inoext[iagext_idx]), 0);	}	/* end no activity for the inodes in the range for ... */	return (0);}/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * * NAME:        doUpdateMap(ld) * * FUNCTION:    processing for LOG_UPDATEMAP record types. * *           IN GENERAL *           ---------- *              The updatemap log record has many sub-types defined in *              ld->log.updatemap.type, but in general, the log record *              data describes file system block extent(s) for which *              the block map (bmap) needs to be marked. * *           IN PARTICULAR *           ------------- *              LOG_ALLOCPXD -- is written when an outline EA is allocated * *                 The log record data is a single PXD describing the *                 filesystem blocks to be marked allocated in the block map. * *              LOG_ALLOCPXDLIST -- is not used in release 1 of JFS * *              LOG_ALLOCXAD -- is not used in release 1 of JFS * *              LOG_ALLOCXADLIST -- is not used in release 1 of JFS * *              LOG_FREEPXD -- is written when a file is truncated and *                             a portion of the extent described by a *                             PXD is released *                          -- is written when an outline EA is freed * *                 The log record data is a single PXD describing the *                 filesystem blocks to be marked free in the block map. * *              LOG_FREEPXDLIST -- is written when a file is compressed *                              -- is written when a file grows and the tail *                                 cannot be extended in-place. **see note * *                 The log record data is a list of PXD's describing the *                 extents to be marked free in the block map. * *              LOG_FREEXAD -- is not used in release 1 of JFS * *              LOG_FREEXADLIST -- is written when a file is truncated * *                 The log record data is a list of XAD's describing the *                 extents to be marked free in the block map. * * **note:  (see reference in LOG_FREEPXDLIST above) * *         Each extent of a file MUST be an even multiple of 4096 byte

⌨️ 快捷键说明

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