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

📄 log_work.c

📁 jfs 源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	 * device.	 */	end_of_transaction = -1;	return (0);}/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * * NAME:        doAfter(ld) * * FUNCTION:    processing for LOG_REDOPAGE  record types. * *           IN GENERAL *           ---------- *              The redopage log rec has many sub-types defined in *              ld->log.redopage.type, but in general, the data belonging *              to the REDOPAGE log record is applied to the disk pages *              described by the address in ld->log.redopage.pxd. * *              Also, depending on the redopage.type, *                - the block map (bmap) may be updated *                - the applicable inode map (imap) may be updated *                - a NoRedoFile filter may be established *                - a NoRedoPage filter may be established * *           IN PARTICULAR *           ------------- *              LOG_BTROOT | LOG_DTREE | LOG_NEW -- describes a dtree root *                                        which has been reset * *                 The log record data is applied to dtroot slots.  The *                 dtree root's freelist needs to be initialized.  The *                 LOG_NEW flag indicates that a dtree root which was a *                 leaf is now an internal node. *                 Specifically: *                     - the dtroot was full and was copied into a new *                       dtree (non-root) node. *                     - after the log record data is applied to this *                       dtree root, only 1 slot will be in use -- it *                       will point to the new dtree node. * *                 One log record of this type describes a single dtree *                 root. * *              LOG_BTROOT | LOG_DTREE --describes an updated dtree root * *                 The log record data is applied to dtroot slots.  This *                 covers the case of dtree root initialization, since *                 dtInitRoot() writes all slots (including free slots) *                 for a dtree root node into the log record. * *                 One log record of this type describes a single dtree *                 root. * *              LOG_DTREE -- describes an updated dtree (non-root) node * *                 The log record data is applied to the storage defined *                 by the pxd. * *                 One log record of this type describes a single dtree *                 root. * *              LOG_DTREE | LOG_NEW --  describes a new dtree (non-root) node * *                 The log record data is applied to the storage defined *                 by the pxd.  The node's freelist is initialized.  The *                 block map is updated for the storage allocated for the *                 new node. * *                 One log record of this type describes a single dtree *                 (non-root) node. * *              LOG_DTREE | LOG_EXTEND -- describes a (non-root) dtree node *                                        which has been extended. * *                 The log record data is applied to the storage defined *                 by the pxd.  The node's freelist is initialized.  The *                 block map is updated for the storage allocated for the *                 extended node. * *                 One log record of this type describes a single dtree *                 (non-root) node. * *              LOG_BTROOT | LOG_XTREE -- describes an updated xtree root * *                 The log record data is applied to the xtree root's *                 slots.  The block map is updated to show blocks defined *                 by the pxd's in updated slots are now in use. * *                 One log record of this type describes a single xtree *                 root. * *              LOG_XTREE | LOG_NEW -- describes a new xtree (non-root) node * *                 The log record data is applied to the xtree node's *                 slots.  The block map is updated to show blocks defined *                 by the pxd's in updated slots are now in use.  The block *                 map is also updated to show that the blocks occupied by *                 the xtree node itself are now in use. * *                 One log record of this type describes a single xtree *                 (non-root) node. * *              LOG_XTREE -- describes an xtree (non-root) node which *                           which has been changed. * *                 The log record data is applied to the xtree node's *                 slots.  The block map is updated to show blocks defined *                 by the pxd's in updated slots are now in use. *                 (Note that when a file is truncated, the slots describing *                 the now deleted blocks are not updated.  File truncation *                 affects the slot containing the xtree header nextindex *                 field.) * *                 One log record of this type describes a single xtree *                 (non-root) node. * *              LOG_INODE -- describes one (4096 byte) page of an inode *                           extent (that is, a page actually containing *                           inodes) which has been updated. * *                 The log record data is applied to the inode extent page, *                 updating from 1 to all of the inodes contained in the *                 page.  (Note that this may include updates to inline *                 EA data.) * *                 ** for this log record, log.redopage.inode contains the *                    inode number of the inode map which owns the page. *                    That is, not the inode number of any inode being *                    changed by the contents of this log record. *                    The inode number of each inode being changed by this *                    log record can be found in the inode's after image *                    in the log record data. * *                 For each inode affected by the log record: *                   -  If the portion of the inode affected by this *                      log data has not been updated by an earlier *                      log record in this session, the log data is *                      copied over the appropriate portion of the *                      inode. *                   -  If the nlink count == 0, *                        o the inode map (imap) is updated to show the *                          inode is free *                        o a NoRedoFile filter is started for the inode *                   -  Otherwise (nlink != 0), *                        o the inode map (imap) is updated to show the inode *                          is allocated. * *                 If at least 1 inode affected by the current log record *                 has nlink != 0, the block map is updated to show that *                 the block(s) containing the inode extent (of which this *                 page is a part) are allocated. * *                 (It is obvious that from this log record we don't have *                 enough information to consider marking the blocks *                 containing the inode extent free.) * *                 One log record of this type describes from 1 to all 8 *                 inodes contained in the page. * *              LOG_DATA --  ** may be used in a future release ** * *                 This is for in-line data (i.e. symlink.) *                 (TBD) * */int doAfter(struct lrd *ld,	/* pointer to log record descriptor */	    int32_t logaddr){	int vol, rc = 0;	int32_t hash;	struct nodofile *nodoptr;	/*	 * 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);	/*	 * If the redopage.type != LOG_INODE, then if there is a	 * NoRedoFile filter in effect for the inode we can skip this	 * log record.	 *	 * N.B. When redopage.type == LOG_INODE, log.redopage.inode is	 *      the owning imap's inode number.  We'll check for NoRedoFile	 *      filter(s) on the inode(s) actually affected by the log	 *      record when we examine the log record data in updatePage().	 */	if (!(ld->log.redopage.type & LOG_INODE)) {		hash = (ld->aggregate + ld->log.redopage.inode) & nodofilehmask;		for (nodoptr = nodofilehash[hash]; nodoptr != NULL;		     nodoptr = nodoptr->next) {			if (ld->aggregate == nodoptr->aggregate &&			    ld->log.redopage.inode == nodoptr->inode)				return (0);		}	}	/*	 * updatePage() takes care of applying the log data.	 * This includes:	 *    - applying log data to the affected page	 *    - updates to the inode map for inodes allocated/free	 *    - updates to the block map for an allocated inode extent	 *    - establishing NoRedoFile or NoRedoExtent filters	 *    - updates to the block map for extents described in an	 *      xtree root or node xadlist	 */	if ((rc = updatePage(ld, logaddr)) != 0) {		fsck_send_msg(lrdo_DAFTUPDPGFAILED, logaddr, rc);		return (rc);	}	/*	 * If this isn't a REDOPAGE log record, we're done	 */	if (ld->type != LOG_REDOPAGE)		return (0);	/*	 * update the block map for a new or extended dtree page and	 * for a new xtree page	 */	switch (ld->log.redopage.type) {	case (LOG_DTREE | LOG_NEW):		/*		 * the pxd describes the (non-root) dtree page		 */	case (LOG_DTREE | LOG_EXTEND):		/*		 * The pxd describes the entire (non-root) dtree page, not		 * just the new extension, but it's always ok to mark allocated		 * something which is already marked that way.		 *		 * (And we don't really know how many of the trailing blocks		 * were newly added here anyway.)		 */	case (LOG_XTREE | LOG_NEW):		/*		 * the pxd describes the (non-root) xtree page		 */		rc = markBmap((struct dmap *) vopen[vol].bmap_ctl, ld->log.redopage.pxd, 1, vol);		if (rc) {			fsck_send_msg(lrdo_DAFTMRKBMPFAILED, logaddr, rc);		}		break;	}	return (rc);}/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * * NAME:        doCommit(ld) * * FUNCTION:    Insert the transaction ID (tid) from the given commit *              record into the commit array */int doCommit(struct lrd *ld){				/* pointer to record descriptor */	int k, hash;	DBG_TRACE(("logredo:Docommit\n"))	    if (comfree == 0)		return (JLOG_NOCOMFREE);	k = comfree;	comfree = com[k].next;	hash = ld->logtid & comhmask;	com[k].next = comhash[hash];	com[k].tid = ld->logtid;	comhash[hash] = k;	return (0);}/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * * NAME:        doExtDtPg() * * FUNCTION:    Rebuild the freelist for each dtpage which has been *                   extended in the current logredo session. * */int doExtDtPg(){	struct ExtDtPg *edpp;	int dedp_rc = 0;	int *buf;	pxd_t a_pxd;	while ((DtPgList != NULL) && (dedp_rc == 0)) {		edpp = DtPgList;		PXDaddress(&a_pxd, edpp->pg_off);		PXDlength(&a_pxd, vopen[edpp->pg_vol].lbperpage);		dedp_rc = bread(edpp->pg_vol, a_pxd, (void **) &buf, PB_UPDATE);		if (dedp_rc) {			fsck_send_msg(lrdo_DEDPBREADFAILED, (long long)edpp->pg_off,				      dedp_rc);			dedp_rc = DTPAGE_READERROR1;		} else {			dedp_rc = dtpg_resetFreeList(edpp->pg_vol, buf);			DtPgList = DtPgList->next;		}	}			/* end while */	return (dedp_rc);}/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * * NAME:        doNoRedoFile() * * FUNCTION:    Add a record for the specified inode to the *              NoRedoFile array. */int doNoRedoFile(struct lrd *ld,	/* pointer to record descriptor */		 uint32_t inum){				/* the inode number for noredofile */	int rc = 0;	struct nodofile *ndptr;	int32_t hash;	int32_t allocated_from_bmap = 0;	/*	 * 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);	/*	 * start NoRedoFile filter for the specified inode by	 * adding a record to the NoRedoFile hash list.	 *	 */	hash = (ld->aggregate + inum) & nodofilehmask;	if (Freenodofile == 0) {#ifdef _JFS_DEBUG		printf("logredo:alloc (d)%d bytes for NoRedoFile filter\n", PSIZE);#endif		fsck_send_msg(lrdo_ALLOC4NOREDOFL, PSIZE);		rc = alloc_storage((uint32_t) PSIZE, (void **) &Nodofilep, &allocated_from_bmap);		if ((rc != 0) || (Nodofilep == NULL)) {			/*			 * NoRedoFile filter allocation failed			 */#ifdef _JFS_DEBUG			printf("logredo:alloc (d)%lld bytes for NoRedoFile filter failed\n", PSIZE);#endif			fsck_send_msg(lrdo_ALLOC4NOREDOFLFAIL, PSIZE);			return (ENOMEM3);		} else if (Nodofilep != NULL) {			/* NoRedoFile filter allocation successful */			if (allocated_from_bmap) {#ifdef _JFS_DEBUG				printf				    ("logredo:alloc (d)%lld bytes for NoRedoFile filter out of bmap allocation\n",				     PSIZE);#endif				fsck_send_msg(lrdo_USINGBMAPALLOC4NRFL);			}		}		/* end NoRedoFile filter allocation successful */		Freenodofile = PSIZE / sizeof (struct nodofile);	}	ndptr = Nodofilep++;	numnodofile++;	Freenodofile--;	ndptr->next = nodofilehash[hash];	nodofilehash[hash] = ndptr;	ndptr->aggregate = ld->aggregate;	ndptr->inode = inum;

⌨️ 快捷键说明

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