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

📄 jfs_xtree.c

📁 jfs-2.4-1.1.7.tar.gz jfs 2.4-1.1.7 源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	/*	 *      extent overflow: insert entry for new extent	 *///insertNew:	xoff = offsetXAD(xad) + MAXXLEN;	xaddr = addressXAD(xad) + MAXXLEN;	nextindex = le16_to_cpu(p->header.nextindex);	/*	 *      if the leaf page is full, insert the new entry and	 *      propagate up the router entry for the new page from split	 *	 * The xtSplitUp() will insert the entry and unpin the leaf page.	 */	if (nextindex == le16_to_cpu(p->header.maxentry)) {		rootsplit = p->header.flag & BT_ROOT;		/* xtSpliUp() unpins leaf pages */		split.mp = mp;		split.index = index + 1;		split.flag = XAD_NEW;		split.off = xoff;	/* split offset */		split.len = len;		split.addr = xaddr;		split.pxdlist = NULL;		if ((rc = xtSplitUp(tid, ip, &split, &btstack)))			return rc;		/*		 * if leaf root has been split, original root has been		 * copied to new child page, i.e., original entry now		 * resides on the new child page;		 */		if (rootsplit) {			ASSERT(p->header.nextindex ==			       cpu_to_le16(XTENTRYSTART + 1));			xad = &p->xad[XTENTRYSTART];			bn = addressXAD(xad);			/* get new child page */			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);			if (rc)				return rc;			BT_MARK_DIRTY(mp, ip);			if (!test_cflag(COMMIT_Nolink, ip)) {				tlck = txLock(tid, ip, mp, tlckXTREE|tlckGROW);				xtlck = (struct xtlock *) & tlck->lock;			}		} else {			/* get back old page */			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);			if (rc)				return rc;		}	}	/*	 *      insert the new entry into the leaf page	 */	else {		/* insert the new entry: mark the entry NEW */		xad = &p->xad[index + 1];		XT_PUTENTRY(xad, XAD_NEW, xoff, len, xaddr);		/* advance next available entry index */		p->header.nextindex =		    cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1);	}	/* get back old entry */	xad = &p->xad[index];	xlen = MAXXLEN;	/*	 * extend old extent	 */      extendOld:	XADlength(xad, xlen);	if (!(xad->flag & XAD_NEW))		xad->flag |= XAD_EXTENDED;	if (!test_cflag(COMMIT_Nolink, ip)) {		xtlck->lwm.offset =		    (xtlck->lwm.offset) ? min(index,					      (int)xtlck->lwm.offset) : index;		xtlck->lwm.length =		    le16_to_cpu(p->header.nextindex) - xtlck->lwm.offset;	}	/* unpin the leaf page */	XT_PUTPAGE(mp);	return rc;}#ifdef _NOTYET/* *      xtTailgate() * * function: split existing 'tail' extent *      (split offset >= start offset of tail extent), and *      relocate and extend the split tail half; * * note: existing extent may or may not have been committed. * caller is responsible for pager buffer cache update, and * working block allocation map update; * update pmap: free old split tail extent, alloc new extent; */int xtTailgate(tid_t tid,		/* transaction id */	       struct inode *ip, s64 xoff,	/* split/new extent offset */	       s32 xlen,	/* new extent length */	       s64 xaddr,	/* new extent address */	       int flag){	int rc = 0;	int cmp;	struct metapage *mp;	/* meta-page buffer */	xtpage_t *p;		/* base B+-tree index page */	s64 bn;	int index, nextindex, llen, rlen;	struct btstack btstack;	/* traverse stack */	struct xtsplit split;	/* split information */	xad_t *xad;	struct tlock *tlck;	struct xtlock *xtlck = 0;	struct tlock *mtlck;	struct maplock *pxdlock;	int rootsplit = 0;/*printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n",        (ulong)xoff, xlen, (ulong)xaddr);*/	/* there must exist extent to be tailgated */	if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT)))		return rc;	/* retrieve search result */	XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);	if (cmp != 0) {		XT_PUTPAGE(mp);		jfs_error(ip->i_sb, "xtTailgate: couldn't find extent");		return -EIO;	}	/* entry found must be last entry */	nextindex = le16_to_cpu(p->header.nextindex);	if (index != nextindex - 1) {		XT_PUTPAGE(mp);		jfs_error(ip->i_sb,			  "xtTailgate: the entry found is not the last entry");		return -EIO;	}	BT_MARK_DIRTY(mp, ip);	/*	 * acquire tlock of the leaf page containing original entry	 */	if (!test_cflag(COMMIT_Nolink, ip)) {		tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);		xtlck = (struct xtlock *) & tlck->lock;	}	/* completely replace extent ? */	xad = &p->xad[index];/*printf("xtTailgate: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n",        (ulong)offsetXAD(xad), lengthXAD(xad), (ulong)addressXAD(xad));*/	if ((llen = xoff - offsetXAD(xad)) == 0)		goto updateOld;	/*	 *      partially replace extent: insert entry for new extent	 *///insertNew:	/*	 *      if the leaf page is full, insert the new entry and	 *      propagate up the router entry for the new page from split	 *	 * The xtSplitUp() will insert the entry and unpin the leaf page.	 */	if (nextindex == le16_to_cpu(p->header.maxentry)) {		rootsplit = p->header.flag & BT_ROOT;		/* xtSpliUp() unpins leaf pages */		split.mp = mp;		split.index = index + 1;		split.flag = XAD_NEW;		split.off = xoff;	/* split offset */		split.len = xlen;		split.addr = xaddr;		split.pxdlist = NULL;		if ((rc = xtSplitUp(tid, ip, &split, &btstack)))			return rc;		/*		 * if leaf root has been split, original root has been		 * copied to new child page, i.e., original entry now		 * resides on the new child page;		 */		if (rootsplit) {			ASSERT(p->header.nextindex ==			       cpu_to_le16(XTENTRYSTART + 1));			xad = &p->xad[XTENTRYSTART];			bn = addressXAD(xad);			/* get new child page */			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);			if (rc)				return rc;			BT_MARK_DIRTY(mp, ip);			if (!test_cflag(COMMIT_Nolink, ip)) {				tlck = txLock(tid, ip, mp, tlckXTREE|tlckGROW);				xtlck = (struct xtlock *) & tlck->lock;			}		} else {			/* get back old page */			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);			if (rc)				return rc;		}	}	/*	 *      insert the new entry into the leaf page	 */	else {		/* insert the new entry: mark the entry NEW */		xad = &p->xad[index + 1];		XT_PUTENTRY(xad, XAD_NEW, xoff, xlen, xaddr);		/* advance next available entry index */		p->header.nextindex =		    cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1);	}	/* get back old XAD */	xad = &p->xad[index];	/*	 * truncate/relocate old extent at split offset	 */      updateOld:	/* update dmap for old/committed/truncated extent */	rlen = lengthXAD(xad) - llen;	if (!(xad->flag & XAD_NEW)) {		/* free from PWMAP at commit */		if (!test_cflag(COMMIT_Nolink, ip)) {			mtlck = txMaplock(tid, ip, tlckMAP);			pxdlock = (struct maplock *) & mtlck->lock;			pxdlock->flag = mlckFREEPXD;			PXDaddress(&pxdlock->pxd, addressXAD(xad) + llen);			PXDlength(&pxdlock->pxd, rlen);			pxdlock->index = 1;		}	} else		/* free from WMAP */		dbFree(ip, addressXAD(xad) + llen, (s64) rlen);	if (llen)		/* truncate */		XADlength(xad, llen);	else		/* replace */		XT_PUTENTRY(xad, XAD_NEW, xoff, xlen, xaddr);	if (!test_cflag(COMMIT_Nolink, ip)) {		xtlck->lwm.offset = (xtlck->lwm.offset) ?		    min(index, (int)xtlck->lwm.offset) : index;		xtlck->lwm.length = le16_to_cpu(p->header.nextindex) -		    xtlck->lwm.offset;	}	/* unpin the leaf page */	XT_PUTPAGE(mp);	return rc;}#endif /* _NOTYET *//* *      xtUpdate() * * function: update XAD; * *      update extent for allocated_but_not_recorded or *      compressed extent; * * parameter: *      nxad    - new XAD; *                logical extent of the specified XAD must be completely *                contained by an existing XAD; */int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad){				/* new XAD */	int rc = 0;	int cmp;	struct metapage *mp;	/* meta-page buffer */	xtpage_t *p;		/* base B+-tree index page */	s64 bn;	int index0, index, newindex, nextindex;	struct btstack btstack;	/* traverse stack */	struct xtsplit split;	/* split information */	xad_t *xad, *lxad, *rxad;	int xflag;	s64 nxoff, xoff;	int nxlen, xlen, lxlen, rxlen;	s64 nxaddr, xaddr;	struct tlock *tlck;	struct xtlock *xtlck = 0;	int rootsplit = 0, newpage = 0;	/* there must exist extent to be tailgated */	nxoff = offsetXAD(nxad);	nxlen = lengthXAD(nxad);	nxaddr = addressXAD(nxad);	if ((rc = xtSearch(ip, nxoff, &cmp, &btstack, XT_INSERT)))		return rc;	/* retrieve search result */	XT_GETSEARCH(ip, btstack.top, bn, mp, p, index0);	if (cmp != 0) {		XT_PUTPAGE(mp);		jfs_error(ip->i_sb, "xtUpdate: Could not find extent");		return -EIO;	}	BT_MARK_DIRTY(mp, ip);	/*	 * acquire tlock of the leaf page containing original entry	 */	if (!test_cflag(COMMIT_Nolink, ip)) {		tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);		xtlck = (struct xtlock *) & tlck->lock;	}	xad = &p->xad[index0];	xflag = xad->flag;	xoff = offsetXAD(xad);	xlen = lengthXAD(xad);	xaddr = addressXAD(xad);	/* nXAD must be completely contained within XAD */	if ((xoff > nxoff) ||	    (nxoff + nxlen > xoff + xlen)) {		XT_PUTPAGE(mp);		jfs_error(ip->i_sb,			  "xtUpdate: nXAD in not completely contained within XAD");		return -EIO;	}	index = index0;	newindex = index + 1;	nextindex = le16_to_cpu(p->header.nextindex);#ifdef  _JFS_WIP_NOCOALESCE	if (xoff < nxoff)		goto updateRight;	/*	 * replace XAD with nXAD	 */      replace:			/* (nxoff == xoff) */	if (nxlen == xlen) {		/* replace XAD with nXAD:recorded */		*xad = *nxad;		xad->flag = xflag & ~XAD_NOTRECORDED;		goto out;	} else			/* (nxlen < xlen) */		goto updateLeft;#endif				/* _JFS_WIP_NOCOALESCE *//* #ifdef _JFS_WIP_COALESCE */	if (xoff < nxoff)		goto coalesceRight;	/*	 * coalesce with left XAD	 *///coalesceLeft: /* (xoff == nxoff) */	/* is XAD first entry of page ? */	if (index == XTENTRYSTART)		goto replace;	/* is nXAD logically and physically contiguous with lXAD ? */	lxad = &p->xad[index - 1];	lxlen = lengthXAD(lxad);	if (!(lxad->flag & XAD_NOTRECORDED) &&	    (nxoff == offsetXAD(lxad) + lxlen) &&	    (nxaddr == addressXAD(lxad) + lxlen) &&	    (lxlen + nxlen < MAXXLEN)) {		/* extend right lXAD */		index0 = index - 1;		XADlength(lxad, lxlen + nxlen);		/* If we just merged two extents together, need to make sure the		 * right extent gets logged.  If the left one is marked XAD_NEW,		 * then we know it will be logged.  Otherwise, mark as		 * XAD_EXTENDED		 */		if (!(lxad->flag & XAD_NEW))			lxad->flag |= XAD_EXTENDED;		if (xlen > nxlen) {			/* truncate XAD */			XADoffset(xad, xoff + nxlen);			XADlength(xad, xlen - nxlen);			XADaddress(xad, xaddr + nxlen);			goto out;		} else {	/* (xlen == nxlen) */			/* remove XAD */			if (index < nextindex - 1)				memmove(&p->xad[index], &p->xad[index + 1],					(nextindex - index -					 1) << L2XTSLOTSIZE);			p->header.nextindex =			    cpu_to_le16(le16_to_cpu(p->header.nextindex) -					1);			index = index0;			newindex = index + 1;			nextindex = le16_to_cpu(p->header.nextindex);			xoff = nxoff = offsetXAD(lxad);			xlen = nxlen = lxlen + nxlen;			xaddr = nxaddr = addressXAD(lxad);			goto coalesceRight;		}	}	/*	 * replace XAD with nXAD	 */      replace:			/* (nxoff == xoff) */	if (nxlen == xlen) {		/* replace XAD with nXAD:recorded */		*xad = *nxad;		xad->flag = xflag & ~XAD_NOTRECORDED;		goto coalesceRight;	} else			/* (nxlen < xlen) */		goto updateLeft;	/*	 * coalesce with right XAD	 */      coalesceRight:		/* (xoff <= nxoff) */	/* is XAD last entry of page ? */	if (newindex == nextindex) {		if (xoff == nxoff)			goto out;		goto updateRight;	}	/* is nXAD logically and physically contiguous with rXAD ? */	rxad = &p->xad[index + 1];	rxlen = lengthXAD(rxad);	if (!(rxad->flag & XAD_NOTRECORDED) &&	    (nxoff + nxlen == offsetXAD(rxad)) &&	    (nxaddr + nxlen == addressXAD(rxad)) &&	    (rxlen + nxlen < MAXXLEN)) {		/* extend left rXAD */		XADoffset(rxad, nxoff);		XADlength(rxad, rxlen + nxlen);		XADaddress(rxad, nxaddr);		/* If we just merged two extents together, need to make sure		 * the left extent gets logged.  If the right one is marked		 * XAD_NEW, then we know it will be logged.  Otherwise, mark as		 * XAD_EXTENDED		 */		if (!(rxad->flag & XAD_NEW))			rxad->flag |= XAD_EXTENDED;		if (xlen > nxlen)			/* truncate XAD */			XADlength(xad, xlen - nxlen);		else {		/* (xlen == nxlen) */			/* remove XAD */			memmove(&p->xad[index], &p->xad[index + 1],				(nextindex - index - 1) << L2XTSLOTSIZE);			p->header.nextindex =			    cpu_to_le16(le16_to_cpu(p->header.nextindex) -					1);		}		goto out;	} else if (xoff == nxoff)		goto out;	if (xoff >= nxoff) {		XT_PUTPAGE(mp);		jfs_error(ip->i_sb, "xtUpdate: xoff >= nxoff");		return -EIO;	}/* #endif _JFS_WIP_COALESCE */	/*	 * split XAD into (lXAD, nXAD):	 *	 *          |---nXAD--->	 * --|----------XAD----------|--	 *   |-lXAD-|	 */      updateRight:		/* (xoff < nxoff) */	/* truncate old XAD as lXAD:not_recorded */	xad = &p->xad[index];	XADlength(xad, nxoff - xoff);	/* insert nXAD:recorded */	if (nextindex == le16_to_cpu(p->header.maxentry)) {		rootsplit = p->header.flag & BT_ROOT;		/* xtSpliUp() unpins leaf pages */		split.mp = mp;		split.index = newindex;		split.flag = xflag & ~XAD_NOTRECORDED;		split.off = nxoff;		split.len = nxlen;		split.addr = nxaddr;		split.pxdlist = NULL;		if ((rc = xtSplitUp(tid, ip, &split, &btstack)))			return rc;		/*		 * if leaf root has been split, original root has been		 * copied to new child page, i.e., original entry now		 * resides on the new child page;		 */		if (rootsplit) {			ASSERT(p->header.nextindex ==			       cpu_to_le16(XTENTRYSTART + 1));			xad = &p->xad[XTENTRYSTART];			bn = addressXAD(xad);			/* get new child page */			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);

⌨️ 快捷键说明

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