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

📄 jfs_txnmgr.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	pxd = &lrd->log.redopage.pxd;	/* log after-image for logredo(): */	lrd->type = cpu_to_le16(LOG_REDOPAGE);	if (jfs_dirtable_inline(tlck->ip)) {		/*		 * The table has been truncated, we've must have deleted		 * the last entry, so don't bother logging this		 */		mp->lid = 0;		grab_metapage(mp);		metapage_homeok(mp);		discard_metapage(mp);		tlck->mp = NULL;		return 0;	}	PXDaddress(pxd, mp->index);	PXDlength(pxd, mp->logical_size >> tblk->sb->s_blocksize_bits);	lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));	/* mark page as homeward bound */	tlck->flag |= tlckWRITEPAGE;	return 0;}/* *	dtLog() * * function:	log dtree tlock and format maplock to update bmap; */static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,	   struct tlock * tlck){	struct metapage *mp;	struct pxd_lock *pxdlock;	pxd_t *pxd;	mp = tlck->mp;	/* initialize as REDOPAGE/NOREDOPAGE record format */	lrd->log.redopage.type = cpu_to_le16(LOG_DTREE);	lrd->log.redopage.l2linesize = cpu_to_le16(L2DTSLOTSIZE);	pxd = &lrd->log.redopage.pxd;	if (tlck->type & tlckBTROOT)		lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT);	/*	 *	page extension via relocation: entry insertion;	 *	page extension in-place: entry insertion;	 *	new right page from page split, reinitialized in-line	 *	root from root page split: entry insertion;	 */	if (tlck->type & (tlckNEW | tlckEXTEND)) {		/* log after-image of the new page for logredo():		 * mark log (LOG_NEW) for logredo() to initialize		 * freelist and update bmap for alloc of the new page;		 */		lrd->type = cpu_to_le16(LOG_REDOPAGE);		if (tlck->type & tlckEXTEND)			lrd->log.redopage.type |= cpu_to_le16(LOG_EXTEND);		else			lrd->log.redopage.type |= cpu_to_le16(LOG_NEW);		PXDaddress(pxd, mp->index);		PXDlength(pxd,			  mp->logical_size >> tblk->sb->s_blocksize_bits);		lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));		/* format a maplock for txUpdateMap() to update bPMAP for		 * alloc of the new page;		 */		if (tlck->type & tlckBTROOT)			return;		tlck->flag |= tlckUPDATEMAP;		pxdlock = (struct pxd_lock *) & tlck->lock;		pxdlock->flag = mlckALLOCPXD;		pxdlock->pxd = *pxd;		pxdlock->index = 1;		/* mark page as homeward bound */		tlck->flag |= tlckWRITEPAGE;		return;	}	/*	 *	entry insertion/deletion,	 *	sibling page link update (old right page before split);	 */	if (tlck->type & (tlckENTRY | tlckRELINK)) {		/* log after-image for logredo(): */		lrd->type = cpu_to_le16(LOG_REDOPAGE);		PXDaddress(pxd, mp->index);		PXDlength(pxd,			  mp->logical_size >> tblk->sb->s_blocksize_bits);		lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));		/* mark page as homeward bound */		tlck->flag |= tlckWRITEPAGE;		return;	}	/*	 *	page deletion: page has been invalidated	 *	page relocation: source extent	 *	 *	a maplock for free of the page has been formatted	 *	at txLock() time);	 */	if (tlck->type & (tlckFREE | tlckRELOCATE)) {		/* log LOG_NOREDOPAGE of the deleted page for logredo()		 * to start NoRedoPage filter and to update bmap for free		 * of the deletd page		 */		lrd->type = cpu_to_le16(LOG_NOREDOPAGE);		pxdlock = (struct pxd_lock *) & tlck->lock;		*pxd = pxdlock->pxd;		lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, NULL));		/* a maplock for txUpdateMap() for free of the page		 * has been formatted at txLock() time;		 */		tlck->flag |= tlckUPDATEMAP;	}	return;}/* *	xtLog() * * function:	log xtree tlock and format maplock to update bmap; */static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,	   struct tlock * tlck){	struct inode *ip;	struct metapage *mp;	xtpage_t *p;	struct xtlock *xtlck;	struct maplock *maplock;	struct xdlistlock *xadlock;	struct pxd_lock *pxdlock;	pxd_t *page_pxd;	int next, lwm, hwm;	ip = tlck->ip;	mp = tlck->mp;	/* initialize as REDOPAGE/NOREDOPAGE record format */	lrd->log.redopage.type = cpu_to_le16(LOG_XTREE);	lrd->log.redopage.l2linesize = cpu_to_le16(L2XTSLOTSIZE);	page_pxd = &lrd->log.redopage.pxd;	if (tlck->type & tlckBTROOT) {		lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT);		p = &JFS_IP(ip)->i_xtroot;		if (S_ISDIR(ip->i_mode))			lrd->log.redopage.type |=			    cpu_to_le16(LOG_DIR_XTREE);	} else		p = (xtpage_t *) mp->data;	next = le16_to_cpu(p->header.nextindex);	xtlck = (struct xtlock *) & tlck->lock;	maplock = (struct maplock *) & tlck->lock;	xadlock = (struct xdlistlock *) maplock;	/*	 *	entry insertion/extension;	 *	sibling page link update (old right page before split);	 */	if (tlck->type & (tlckNEW | tlckGROW | tlckRELINK)) {		/* log after-image for logredo():		 * logredo() will update bmap for alloc of new/extended		 * extents (XAD_NEW|XAD_EXTEND) of XAD[lwm:next) from		 * after-image of XADlist;		 * logredo() resets (XAD_NEW|XAD_EXTEND) flag when		 * applying the after-image to the meta-data page.		 */		lrd->type = cpu_to_le16(LOG_REDOPAGE);		PXDaddress(page_pxd, mp->index);		PXDlength(page_pxd,			  mp->logical_size >> tblk->sb->s_blocksize_bits);		lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));		/* format a maplock for txUpdateMap() to update bPMAP		 * for alloc of new/extended extents of XAD[lwm:next)		 * from the page itself;		 * txUpdateMap() resets (XAD_NEW|XAD_EXTEND) flag.		 */		lwm = xtlck->lwm.offset;		if (lwm == 0)			lwm = XTPAGEMAXSLOT;		if (lwm == next)			goto out;		if (lwm > next) {			jfs_err("xtLog: lwm > next\n");			goto out;		}		tlck->flag |= tlckUPDATEMAP;		xadlock->flag = mlckALLOCXADLIST;		xadlock->count = next - lwm;		if ((xadlock->count <= 4) && (tblk->xflag & COMMIT_LAZY)) {			int i;			pxd_t *pxd;			/*			 * Lazy commit may allow xtree to be modified before			 * txUpdateMap runs.  Copy xad into linelock to			 * preserve correct data.			 *			 * We can fit twice as may pxd's as xads in the lock			 */			xadlock->flag = mlckALLOCPXDLIST;			pxd = xadlock->xdlist = &xtlck->pxdlock;			for (i = 0; i < xadlock->count; i++) {				PXDaddress(pxd, addressXAD(&p->xad[lwm + i]));				PXDlength(pxd, lengthXAD(&p->xad[lwm + i]));				p->xad[lwm + i].flag &=				    ~(XAD_NEW | XAD_EXTENDED);				pxd++;			}		} else {			/*			 * xdlist will point to into inode's xtree, ensure			 * that transaction is not committed lazily.			 */			xadlock->flag = mlckALLOCXADLIST;			xadlock->xdlist = &p->xad[lwm];			tblk->xflag &= ~COMMIT_LAZY;		}		jfs_info("xtLog: alloc ip:0x%p mp:0x%p tlck:0x%p lwm:%d "			 "count:%d", tlck->ip, mp, tlck, lwm, xadlock->count);		maplock->index = 1;	      out:		/* mark page as homeward bound */		tlck->flag |= tlckWRITEPAGE;		return;	}	/*	 *	page deletion: file deletion/truncation (ref. xtTruncate())	 *	 * (page will be invalidated after log is written and bmap	 * is updated from the page);	 */	if (tlck->type & tlckFREE) {		/* LOG_NOREDOPAGE log for NoRedoPage filter:		 * if page free from file delete, NoRedoFile filter from		 * inode image of zero link count will subsume NoRedoPage		 * filters for each page;		 * if page free from file truncattion, write NoRedoPage		 * filter;		 *		 * upadte of block allocation map for the page itself:		 * if page free from deletion and truncation, LOG_UPDATEMAP		 * log for the page itself is generated from processing		 * its parent page xad entries;		 */		/* if page free from file truncation, log LOG_NOREDOPAGE		 * of the deleted page for logredo() to start NoRedoPage		 * filter for the page;		 */		if (tblk->xflag & COMMIT_TRUNCATE) {			/* write NOREDOPAGE for the page */			lrd->type = cpu_to_le16(LOG_NOREDOPAGE);			PXDaddress(page_pxd, mp->index);			PXDlength(page_pxd,				  mp->logical_size >> tblk->sb->				  s_blocksize_bits);			lrd->backchain =			    cpu_to_le32(lmLog(log, tblk, lrd, NULL));			if (tlck->type & tlckBTROOT) {				/* Empty xtree must be logged */				lrd->type = cpu_to_le16(LOG_REDOPAGE);				lrd->backchain =				    cpu_to_le32(lmLog(log, tblk, lrd, tlck));			}		}		/* init LOG_UPDATEMAP of the freed extents		 * XAD[XTENTRYSTART:hwm) from the deleted page itself		 * for logredo() to update bmap;		 */		lrd->type = cpu_to_le16(LOG_UPDATEMAP);		lrd->log.updatemap.type = cpu_to_le16(LOG_FREEXADLIST);		xtlck = (struct xtlock *) & tlck->lock;		hwm = xtlck->hwm.offset;		lrd->log.updatemap.nxd =		    cpu_to_le16(hwm - XTENTRYSTART + 1);		/* reformat linelock for lmLog() */		xtlck->header.offset = XTENTRYSTART;		xtlck->header.length = hwm - XTENTRYSTART + 1;		xtlck->index = 1;		lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));		/* format a maplock for txUpdateMap() to update bmap		 * to free extents of XAD[XTENTRYSTART:hwm) from the		 * deleted page itself;		 */		tlck->flag |= tlckUPDATEMAP;		xadlock->count = hwm - XTENTRYSTART + 1;		if ((xadlock->count <= 4) && (tblk->xflag & COMMIT_LAZY)) {			int i;			pxd_t *pxd;			/*			 * Lazy commit may allow xtree to be modified before			 * txUpdateMap runs.  Copy xad into linelock to			 * preserve correct data.			 *			 * We can fit twice as may pxd's as xads in the lock			 */			xadlock->flag = mlckFREEPXDLIST;			pxd = xadlock->xdlist = &xtlck->pxdlock;			for (i = 0; i < xadlock->count; i++) {				PXDaddress(pxd,					addressXAD(&p->xad[XTENTRYSTART + i]));				PXDlength(pxd,					lengthXAD(&p->xad[XTENTRYSTART + i]));				pxd++;			}		} else {			/*			 * xdlist will point to into inode's xtree, ensure			 * that transaction is not committed lazily.			 */			xadlock->flag = mlckFREEXADLIST;			xadlock->xdlist = &p->xad[XTENTRYSTART];			tblk->xflag &= ~COMMIT_LAZY;		}		jfs_info("xtLog: free ip:0x%p mp:0x%p count:%d lwm:2",			 tlck->ip, mp, xadlock->count);		maplock->index = 1;		/* mark page as invalid */		if (((tblk->xflag & COMMIT_PWMAP) || S_ISDIR(ip->i_mode))		    && !(tlck->type & tlckBTROOT))			tlck->flag |= tlckFREEPAGE;		/*		   else (tblk->xflag & COMMIT_PMAP)		   ? release the page;		 */		return;	}	/*	 *	page/entry truncation: file truncation (ref. xtTruncate())	 *	 *	|----------+------+------+---------------|	 *		   |      |      |	 *		   |      |     hwm - hwm before truncation	 *		   |     next - truncation point	 *		  lwm - lwm before truncation	 * header ?	 */	if (tlck->type & tlckTRUNCATE) {		/* This odd declaration suppresses a bogus gcc warning */		pxd_t pxd = pxd;	/* truncated extent of xad */		int twm;		/*		 * For truncation the entire linelock may be used, so it would		 * be difficult to store xad list in linelock itself.		 * Therefore, we'll just force transaction to be committed		 * synchronously, so that xtree pages won't be changed before		 * txUpdateMap runs.		 */		tblk->xflag &= ~COMMIT_LAZY;		lwm = xtlck->lwm.offset;		if (lwm == 0)			lwm = XTPAGEMAXSLOT;		hwm = xtlck->hwm.offset;		twm = xtlck->twm.offset;		/*		 *	write log records		 */		/* log after-image for logredo():		 *		 * logredo() will update bmap for alloc of new/extended		 * extents (XAD_NEW|XAD_EXTEND) of XAD[lwm:next) from		 * after-image of XADlist;		 * logredo() resets (XAD_NEW|XAD_EXTEND) flag when		 * applying the after-image to the meta-data page.		 */		lrd->type = cpu_to_le16(LOG_REDOPAGE);		PXDaddress(page_pxd, mp->index);		PXDlength(page_pxd,			  mp->logical_size >> tblk->sb->s_blocksize_bits);		lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));		/*		 * truncate entry XAD[twm == next - 1]:		 */		if (twm == next - 1) {			/* init LOG_UPDATEMAP for logredo() to update bmap for			 * free of truncated delta extent of the truncated			 * entry XAD[next - 1]:			 * (xtlck->pxdlock = truncated delta extent);			 */			pxdlock = (struct pxd_lock *) & xtlck->pxdlock;			/* assert(pxdlock->type & tlckTRUNCATE); */			lrd->type = cpu_to_le16(LOG_UPDATEMAP);			lrd->log.updatemap.type = cpu_to_le16(LOG_FREEPXD);			lrd->log.updatemap.nxd = cpu_to_le16(1);			lrd->log.updatemap.pxd = pxdlock->pxd;			pxd = pxdlock->pxd;	/* save to format maplock */			lrd->backchain =			    cpu_to_le32(lmLog(log, tblk, lrd, NULL));		}		/*		 * free entries XAD[next:hwm]:		 */		if (hwm >= next) {			/* init LOG_UPDATEMAP of the freed extents			 * XAD[next:hwm] from the deleted page itself			 * for logredo() to update bmap;			 */			lrd->type = cpu_to_le16(LOG_UPDATEMAP);			lrd->log.updatemap.type =			    cpu_to_le16(LOG_FREEXADLIST);			xtlck = (struct xtlock *) & tlck->lock;			hwm = xtlck->hwm.offset;			lrd->log.updatemap.nxd =			    cpu_to_le16(hwm - next + 1);			/* reformat linelock for lmLog() */			xtlck->header.offset = next;			xtlck->header.length = hwm - next + 1;			xtlck->index = 1;			lrd->backchain =			    cpu_to_le32(lmLog(log, tblk, lrd, tlck));		}		/*		 *	format maplock(s) for txUpdateMap() to update bmap		 */		maplock->index = 0;		/*		 * allocate entries XAD[lwm:next):		 */		if (lwm < next) {			/* format a maplock for txUpdateMap() to update bPMAP			 * for alloc of new/extended extents of XAD[lwm:next)			 * from the page itself;			 * txUpdateMap() resets (XAD_NEW|XAD_EXTEND) flag.			 */			tlck->flag |= tlckUPDATEMAP;			xadlock->flag = mlckALLOCXADLIST;			xadlock->count = next - lwm;			xadlock->xdlist = &p->xad[lwm];			jfs_info("xtLog: alloc ip:0x%p mp:0x%p count:%d "				 "lwm:%d next:%d",				 tlck->ip, mp, xadlock->count, lwm, next);			maplock->index++;			xadlock++;		}		/*		 * truncate entry XAD[twm == next - 1]:		 */		if (twm == next - 1) {			/* format a maplock for txUpdateMap() to update bmap			 * to free truncated delta extent of the truncated			 * entry XAD[next - 1];			 * (xtlck->pxdlock = truncated delta extent);			 */			tlck->flag |= tlckUPDATEMAP;			pxdlock = (struct pxd_lock *) xadlock;			pxdlock->flag = mlckFREEPXD;			pxdlock->count = 1;			pxdlock->pxd = pxd;			jfs_info("xtLog: truncate ip:0x%p mp:0x%p count:%d "				 "hwm:%d", ip, mp, pxdlock->count, hwm);			maplock->index++;			xadlock++;		}		/*		 * free entries XAD[next:hwm]:		 */		if (hwm >= next) {			/* format a maplock for txUpdateMap() to update bmap			 * to free extents of XAD[next:hwm] from thedeleted			 * page itself;			 */			tlck->flag |= tlckUPDATEMAP;			xadlock->flag = mlckFREEXADLIST;			xadlock->count = hwm - next + 1;			xadlock->xdlist = &p->xad[next];			jfs_info("xtLog: free ip:0x%p mp:0x%p count:%d "				 "next:%d hwm:%d",				 tlck->ip, mp, xadlock->count, next, hwm);			maplock->index++;		}		/* mark page as homeward bound */		tlck->flag |= tlckWRITEPAGE;	}	return;}/* *	mapLog() *

⌨️ 快捷键说明

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