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

📄 log_work.c

📁 jfs 源码
💻 C
📖 第 1 页 / 共 5 页
字号:
 * * **note:  (see reference in LOG_FREEPXDLIST above) * *         Each extent of a file MUST be an even multiple of 4096 byte *         pages, except the last extent, which need only be an even *         multiple of filesystem blocks.  This means that, if the last *         extent is not a whole page, then it must be extended to a *         whole page before another extent can be added.  If the *         filesystem blocks immediately following the current last *         extent are not available, then it is necessary to select *         a larger storage area and copy the contents of the current *         last extent and the new data (the reason the file is being *         extended in the first place) into it. * *         To illustrate: *            suppose the filesystem block size is 1024 and a particular *            files is 9216 bytes long, stored as *                1 extent 8 fs blocks   (8192 bytes = 2 * 4096) and *                1 extent 1 fs block    (1024 bytes) *            now suppose another 5120 bytes are appended to the file. *            The 2nd extent must be extended because it must either *            become an even multiple of 4096 or it must remain the last *            extent in the file. *            Both: *                          1 extent 8 fs blocks  (8192 bytes) *                          1 extent 6 fs blocks  (6144 bytes) *            and: *                          1 extent 8 fs blocks  (8192 bytes) *                          1 extent 4 fs blocks  (4096 bytes) *                          1 extent 2 fs blocks  (2048 bytes) *            are possible and correct outcomes. * * * NOTE:  Since UPDATEMAP log records only affect the block map, *        the noredofile hash chain is not checked and the transaction *        should not be skipped. * *        When a file system object is deleted, UPDATEMAP log records *        are created (as appropriate) to release storage from (and *        possibly for) metadata xtree pages.  No NoRedoPage log records *        are written for these pages. * */int doUpdateMap(struct lrd *ld){				/* pointer to log record descriptor */	int i, vol, rc = 0;	xad_t *l_xad;	pxd_t *l_pxd;	pxd_t pxd1;	/*	 * 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 (ld->log.updatemap.type & LOG_FREEXADLIST) {		/*		 * The data area contains an array of XAD's, with		 * updatemap.nxd elements.		 */		l_xad = (xad_t *) afterdata;		for (i = 0; i < ld->log.updatemap.nxd; i++) {			PXDaddress(&pxd1, addressXAD(l_xad));			PXDlength(&pxd1, lengthXAD(l_xad));			rc = markBmap((struct dmap *) vopen[vol].bmap_ctl, pxd1, 0, vol);			if (rc != 0) {				return (rc);			}			l_xad += 1;		}	} else if (ld->log.updatemap.type & LOG_FREEPXDLIST) {		/*		 * The data area contains an array of PXD's, with		 * updatemap.nxd elements.		 */		l_pxd = (pxd_t *) afterdata;		for (i = 0; i < ld->log.updatemap.nxd; i++, l_pxd++)			rc = markBmap((struct dmap *) vopen[vol].bmap_ctl, *l_pxd, 0, vol);		if (rc != 0) {			return (rc);		}	} else if (ld->log.updatemap.type & LOG_FREEPXD) {		/*		 * The updatemap.nxd should be 1 in this case.		 */		if (ld->log.updatemap.nxd > 1)			fsError(LOGRCERR, vol, ld->log.updatemap.nxd);		rc = markBmap((struct dmap *) vopen[vol].bmap_ctl, ld->log.updatemap.pxd, 0, vol);		if (rc != 0) {			return (rc);		}	} else if (ld->log.updatemap.type & LOG_ALLOCPXD) {		/*		 * The updatemap.nxd should be 1 in this case.		 */		if (ld->log.updatemap.nxd > 1)			fsError(LOGRCERR, vol, ld->log.updatemap.nxd);		rc = markBmap((struct dmap *) vopen[vol].bmap_ctl, ld->log.updatemap.pxd, 1, vol);		if (rc != 0) {			return (rc);		}	} else		fsck_send_msg(lrdo_DUMPUNKNOWNTYPE);	return (0);}/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * * NAME:        dtpg_resetFreeList(ld) * * FUNCTION:    Reset the freelist in the given Directory Btree (nonroot) * 		node. * * NOTE:        none * */int dtpg_resetFreeList(int32_t vol, int *buf){				/* buf contains on-disk page image */	int16_t pxd_len;	int16_t nslots;		/* number of slots in log.redopage.pxd */	dtpage_t *dtpg;	int16_t stbl_nslots;	/* number of slots occupied by				 * the stbl for the page				 */	int8_t slot_map[DTPAGEMAXSLOT];	int8_t *slot_table;	int16_t sidx, slot_idx = 0;	struct dtslot *this_slot;	struct dtslot *last_slot = 0;	struct idtentry *intern_hdr_slot;	struct ldtentry *leaf_hdr_slot;	dtpg = (dtpage_t *) buf;	if (dtpg->header.nextindex == -1) {		/*		 * the stbl is full, no slots		 * can be available		 */		dtpg->header.freecnt = 0;		dtpg->header.freelist = -1;		return 0;	}	/* the stbl isn't full. slots may be free. */	/*	 * The dtree page size is 512, 1024, 2048, or 4096 bytes.	 * We need to know how many slots it contains and how many	 * slots are occupied by its slot table (stbl).	 */	pxd_len = (lengthPXD(&dtpg->header.self)) << vopen[vol].l2bsize;	switch (pxd_len) {	case DT8THPGNODEBYTES:	/* 512 bytes */		nslots = DT8THPGNODESLOTS;		stbl_nslots = DT8THPGNODETSLOTS;		break;	case DTQTRPGNODEBYTES:	/* 1024 bytes */		nslots = DTQTRPGNODESLOTS;		stbl_nslots = DTQTRPGNODETSLOTS;		break;	case DTHALFPGNODEBYTES:	/* 2048 bytes */		nslots = DTHALFPGNODESLOTS;		stbl_nslots = DTHALFPGNODETSLOTS;		break;	default:		/* 4096 bytes */		nslots = DTFULLPGNODESLOTS;		stbl_nslots = DTFULLPGNODETSLOTS;		break;	}			/* end switch */	/*	 * clear the slot map	 */	for (sidx = 0; sidx < nslots; sidx++) {		slot_map[sidx] = 0;	}	/*	 * account for the header and for the stbl slots	 */	slot_map[0] = -1;	/* the header */	for (sidx = 0; sidx < stbl_nslots; sidx++) {		slot_map[dtpg->header.stblindex + sidx] = -1;	}			/* end for */	slot_table = (int8_t *) & (dtpg->slot[dtpg->header.stblindex]);	/*	 * figure out which slots are in use	 */	for (sidx = 0; sidx < dtpg->header.nextindex; sidx++) {		/*		 * the dir entry header slot		 */		/*		 * If the index is out of bounds or if we've		 * already seen it in use then something is		 * seriously wrong and we need a full fsck.		 * Since the problem could have been caused		 * by something in this logredo session,		 * signal fsck to reformat the log.		 */		if ((slot_table[sidx] >= nslots) || (slot_map[slot_table[sidx]] != 0)) {			fsck_send_msg(lrdo_DPRFBADSTBLENTRY,				      (long long) (addressPXD(&dtpg->header.self)));			return (DTPAGE_BADSTBLENTRY1);		}		/* endif */		slot_map[slot_table[sidx]] = -1;		/*		 * any continuation slots for the dir entry		 */		if ((dtpg->header.flag & BT_LEAF) == BT_LEAF) {			leaf_hdr_slot = (struct ldtentry *)			    &(dtpg->slot[slot_table[sidx]]);			slot_idx = leaf_hdr_slot->next;		} else {	/* internal page */			intern_hdr_slot = (struct idtentry *)			    &(dtpg->slot[slot_table[sidx]]);			slot_idx = intern_hdr_slot->next;		}		/* end else internal page */		while (slot_idx != -1) {			/*			 * if the index is out of bounds or			 * if we've already seen it in use then			 * something is seriously wrong and we			 * need a full fsck.			 * Since the problem could have been caused			 * by something in this logredo session,			 * signal fsck to reformat the log.			 */			if ((slot_idx >= nslots) || (slot_map[slot_idx] != 0)) {				fsck_send_msg(lrdo_DPRFBADSLOTNXTIDX,					      (long long) (addressPXD(&dtpg->header.self)));				return (DTPAGE_BADSLOTNEXTIDX1);			}			/* endif */			slot_map[slot_idx] = -1;			this_slot = &(dtpg->slot[slot_idx]);			slot_idx = this_slot->next;		}		/* end while slot_idx */	}			/* end for sidx */	/*	 * find the first available slot	 */	dtpg->header.freecnt = 0;	/* assume none free */	dtpg->header.freelist = -1;	/* assume none free */	for (sidx = 0; ((sidx < nslots) && (dtpg->header.freecnt == 0)); sidx++) {		if (slot_map[sidx] == 0) {			dtpg->header.freecnt = 1;			dtpg->header.freelist = sidx;			slot_idx = sidx;			last_slot = &(dtpg->slot[sidx]);		}		/* end if */	}			/* end for */	/*	 * count and chain together all available slots	 */	if (dtpg->header.freecnt != 0) {	/* found a free one */		for (sidx = (slot_idx + 1); sidx < nslots; sidx++) {			if (slot_map[sidx] == 0) {				last_slot->next = sidx;				dtpg->header.freecnt += 1;				last_slot = &(dtpg->slot[sidx]);			}	/* end if */		}		/* end for */		last_slot->next = -1;	/* terminate the chain */	}	/* end found a free one */	return (0);}/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * * NAME:        dtrt_resetFreeList(ld) * * FUNCTION:    Reset the freelist in the given Directory inode Btree root. * * NOTE:        none */int dtrt_resetFreeList(int32_t vol, struct doblk *db, struct lrd *ld, caddr_t buf_btroot){	dtroot_t *dtrt;	int8_t slot_map[DTROOTMAXSLOT];	int16_t sidx, slot_idx = 0;	struct dtslot *this_slot;	struct dtslot *last_slot = 0;	struct idtentry *intern_hdr_slot;	struct ldtentry *leaf_hdr_slot;	/*	   * The doblk.i_dtroot (or doblk.dtpage_word) tracks which slots	   * slots have been updated, but since some of those updates may	   * be deletions, we can't use it to create the freelist.	 */	dtrt = (dtroot_t *) buf_btroot;	if (dtrt->header.nextindex == -1) {		/*		 * the stbl is full, no slots		 * can be available		 */		dtrt->header.freecnt = 0;		dtrt->header.freelist = -1;		return 0;	}	/* the stbl isn't full. slots may be free. */	/*	 * clear the slot map	 */	for (sidx = 0; sidx < DTROOTMAXSLOT; sidx++) {		slot_map[sidx] = 0;	}	slot_map[0] = -1;	/* the header occupies this space */	/*	 * figure out which slots are in use	 */	for (sidx = 0; sidx < dtrt->header.nextindex; sidx++) {		/*		 * the dir entry header slot		 */		/*		 * If the index is out of bounds or if we've		 * already seen it in use then something is		 * seriously wrong and we need a full fsck.		 * Since the problem could have been caused		 * by something in this logredo session,		 * signal fsck to reformat the log.		 */		if ((dtrt->header.stbl[sidx] >= DTROOTMAXSLOT) ||		    (slot_map[dtrt->header.stbl[sidx]] != 0)) {			fsck_send_msg(lrdo_DRRFBADSTBLENTRY);			return (DTPAGE_BADSTBLENTRY2);		}		/* endif */		slot_map[dtrt->header.stbl[sidx]] = -1;		/*		 * any continuation slots for the dir entry		 */		if ((dtrt->header.flag & BT_LEAF) == BT_LEAF) {			leaf_hdr_slot = (struct ldtentry *)			    &(dtrt->slot[dtrt->header.stbl[sidx]]);			slot_idx = leaf_hdr_slot->next;		} else {	/* internal page */			intern_hdr_slot = (struct idtentry *)			    &(dtrt->slot[dtrt->header.stbl[sidx]]);			slot_idx = intern_hdr_slot->next;		}		/* end else internal page */		while (slot_idx != -1) {			/*			 * if the index is out of bounds or if we've			 * already seen it in use then something is			 * seriously wrong and we need a full fsck.			 *			 * Since the problem could have been caused by			 * something in this logredo session, signal			 * fsck to reformat the log.			 */			if ((slot_idx >= DTROOTMAXSLOT) || (slot_map[slot_idx] != 0)) {				fsck_send_msg(lrdo_DRRFBADSLOTNXTIDX);				return (DTPAGE_BADSLOTNEXTIDX2);			}			/* endif */			slot_map[slot_idx] = -1;			this_slot = &(dtrt->slot[slot_idx]);			slot_idx = this_slot->next;		}		/* end while slot_idx */	}			/* end for sidx */	/*	 * find the first available slot	 */	dtrt->header.freecnt = 0;	/* assume none free */	dtrt->header.freelist = -1;	/* assume none free */	for (sidx = 0; ((sidx < DTROOTMAXSLOT)			&& (dtrt->header.freecnt == 0)); sidx++) {		if (slot_map[sidx] == 0) {			dtrt->header.freecnt = 1;			dtrt->header.freelist = sidx;			slot_idx = sidx;			last_slot = &(dtrt->slot[sidx]);		}	}	/*	 * count and chain together all available slots	 */	if (dtrt->header.freecnt != 0) {	/* found a free one */		for (sidx = (slot_idx + 1); sidx < DTROOTMAXSLOT; sidx++) {			if (slot_map[sidx] == 0) {

⌨️ 快捷键说明

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