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

📄 jfs_xtree.c

📁 jfs-2.4-1.1.7.tar.gz jfs 2.4-1.1.7 源码
💻 C
📖 第 1 页 / 共 5 页
字号:
			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;			/* is nXAD on new page ? */			if (newindex >			    (le16_to_cpu(p->header.maxentry) >> 1)) {				newindex =				    newindex -				    le16_to_cpu(p->header.nextindex) +				    XTENTRYSTART;				newpage = 1;			}		}	} else {		/* if insert into middle, shift right remaining entries */		if (newindex < nextindex)			memmove(&p->xad[newindex + 1], &p->xad[newindex],				(nextindex - newindex) << L2XTSLOTSIZE);		/* insert the entry */		xad = &p->xad[newindex];		*xad = *nxad;		xad->flag = xflag & ~XAD_NOTRECORDED;		/* advance next available entry index. */		p->header.nextindex =		    cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1);	}	/*	 * does nXAD force 3-way split ?	 *	 *          |---nXAD--->|	 * --|----------XAD-------------|--	 *   |-lXAD-|           |-rXAD -|	 */	if (nxoff + nxlen == xoff + xlen)		goto out;	/* reorient nXAD as XAD for further split XAD into (nXAD, rXAD) */	if (newpage) {		/* close out old page */		if (!test_cflag(COMMIT_Nolink, ip)) {			xtlck->lwm.offset = (xtlck->lwm.offset) ?			    min(index0, (int)xtlck->lwm.offset) : index0;			xtlck->lwm.length =			    le16_to_cpu(p->header.nextindex) -			    xtlck->lwm.offset;		}		bn = le64_to_cpu(p->header.next);		XT_PUTPAGE(mp);		/* get new right 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;		}		index0 = index = newindex;	} else		index++;	newindex = index + 1;	nextindex = le16_to_cpu(p->header.nextindex);	xlen = xlen - (nxoff - xoff);	xoff = nxoff;	xaddr = nxaddr;	/* recompute split pages */	if (nextindex == le16_to_cpu(p->header.maxentry)) {		XT_PUTPAGE(mp);		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: xtSearch failed");			return -EIO;		}		if (index0 != index) {			XT_PUTPAGE(mp);			jfs_error(ip->i_sb,				  "xtUpdate: unexpected value of index");			return -EIO;		}	}	/*	 * split XAD into (nXAD, rXAD)	 *	 *          ---nXAD---|	 * --|----------XAD----------|--	 *                    |-rXAD-|	 */      updateLeft:		/* (nxoff == xoff) && (nxlen < xlen) */	/* update old XAD with nXAD:recorded */	xad = &p->xad[index];	*xad = *nxad;	xad->flag = xflag & ~XAD_NOTRECORDED;	/* insert rXAD:not_recorded */	xoff = xoff + nxlen;	xlen = xlen - nxlen;	xaddr = xaddr + nxlen;	if (nextindex == le16_to_cpu(p->header.maxentry)) {		rootsplit = p->header.flag & BT_ROOT;/*printf("xtUpdate.updateLeft.split p:0x%p\n", p);*/		/* xtSpliUp() unpins leaf pages */		split.mp = mp;		split.index = newindex;		split.flag = xflag;		split.off = xoff;		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;		}	} else {		/* if insert into middle, shift right remaining entries */		if (newindex < nextindex)			memmove(&p->xad[newindex + 1], &p->xad[newindex],				(nextindex - newindex) << L2XTSLOTSIZE);		/* insert the entry */		xad = &p->xad[newindex];		XT_PUTENTRY(xad, xflag, xoff, xlen, xaddr);		/* advance next available entry index. */		p->header.nextindex =		    cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1);	}      out:	if (!test_cflag(COMMIT_Nolink, ip)) {		xtlck->lwm.offset = (xtlck->lwm.offset) ?		    min(index0, (int)xtlck->lwm.offset) : index0;		xtlck->lwm.length = le16_to_cpu(p->header.nextindex) -		    xtlck->lwm.offset;	}	/* unpin the leaf page */	XT_PUTPAGE(mp);	return rc;}/* *      xtAppend() * * function: grow in append mode from contiguous region specified ; * * parameter: *      tid             - transaction id; *      ip              - file object; *      xflag           - extent flag: *      xoff            - extent offset; *      maxblocks       - max extent length; *      xlen            - extent length (in/out); *      xaddrp          - extent address pointer (in/out): *      flag            - * * return: */int xtAppend(tid_t tid,		/* transaction id */	     struct inode *ip, int xflag, s64 xoff, s32 maxblocks,		     s32 * xlenp,	/* (in/out) */	     s64 * xaddrp,	/* (in/out) */	     int flag){	int rc = 0;	struct metapage *mp;	/* meta-page buffer */	xtpage_t *p;		/* base B+-tree index page */	s64 bn, xaddr;	int index, nextindex;	struct btstack btstack;	/* traverse stack */	struct xtsplit split;	/* split information */	xad_t *xad;	int cmp;	struct tlock *tlck;	struct xtlock *xtlck;	int nsplit, nblocks, xlen;	struct pxdlist pxdlist;	pxd_t *pxd;	xaddr = *xaddrp;	xlen = *xlenp;	jfs_info("xtAppend: xoff:0x%lx maxblocks:%d xlen:%d xaddr:0x%lx",		 (ulong) xoff, maxblocks, xlen, (ulong) xaddr);	/*	 *      search for the entry location at which to insert:	 *	 * xtFastSearch() and xtSearch() both returns (leaf page	 * pinned, index at which to insert).	 * n.b. xtSearch() may return index of maxentry of	 * the full page.	 */	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) {		rc = -EEXIST;		goto out;	}//insert:	/*	 *      insert entry for new extent	 */	xflag |= XAD_NEW;	/*	 *      if the leaf page is full, split the page and	 *      propagate up the router entry for the new page from split	 *	 * The xtSplitUp() will insert the entry and unpin the leaf page.	 */	nextindex = le16_to_cpu(p->header.nextindex);	if (nextindex < le16_to_cpu(p->header.maxentry))		goto insertLeaf;	/*	 * allocate new index blocks to cover index page split(s)	 */	nsplit = btstack.nsplit;	split.pxdlist = &pxdlist;	pxdlist.maxnpxd = pxdlist.npxd = 0;	pxd = &pxdlist.pxd[0];	nblocks = JFS_SBI(ip->i_sb)->nbperpage;	for (; nsplit > 0; nsplit--, pxd++, xaddr += nblocks, maxblocks -= nblocks) {			if ((rc = dbAllocBottomUp(ip, xaddr, (s64) nblocks)) == 0) {			PXDaddress(pxd, xaddr);			PXDlength(pxd, nblocks);			pxdlist.maxnpxd++;			continue;		}		/* undo allocation */		goto out;	}	xlen = min(xlen, maxblocks);		/*	 * allocate data extent requested	 */	if ((rc = dbAllocBottomUp(ip, xaddr, (s64) xlen)))		goto out;	split.mp = mp;	split.index = index;	split.flag = xflag;	split.off = xoff;	split.len = xlen;	split.addr = xaddr;	if ((rc = xtSplitUp(tid, ip, &split, &btstack))) {		/* undo data extent allocation */		dbFree(ip, *xaddrp, (s64) * xlenp);		return rc;	}	*xaddrp = xaddr;	*xlenp = xlen;	return 0;	/*	 *      insert the new entry into the leaf page	 */      insertLeaf:	/*	 * allocate data extent requested	 */	if ((rc = dbAllocBottomUp(ip, xaddr, (s64) xlen)))		goto out;	BT_MARK_DIRTY(mp, ip);	/*	 * acquire a transaction lock on the leaf page;	 *	 * action: xad insertion/extension;	 */	tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);	xtlck = (struct xtlock *) & tlck->lock;	/* insert the new entry: mark the entry NEW */	xad = &p->xad[index];	XT_PUTENTRY(xad, xflag, xoff, xlen, xaddr);	/* advance next available entry index */	p->header.nextindex =	    cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1);	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;	*xaddrp = xaddr;	*xlenp = xlen;      out:	/* unpin the leaf page */	XT_PUTPAGE(mp);	return rc;}#ifdef _STILL_TO_PORT/* - TBD for defragmentaion/reorganization - * *      xtDelete() * * function: *      delete the entry with the specified key. * *      N.B.: whole extent of the entry is assumed to be deleted. * * parameter: * * return: *       ENOENT: if the entry is not found. * * exception: */int xtDelete(tid_t tid, struct inode *ip, s64 xoff, s32 xlen, int flag){	int rc = 0;	struct btstack btstack;	int cmp;	s64 bn;	struct metapage *mp;	xtpage_t *p;	int index, nextindex;	struct tlock *tlck;	struct xtlock *xtlck;	/*	 * find the matching entry; xtSearch() pins the page	 */	if ((rc = xtSearch(ip, xoff, &cmp, &btstack, 0)))		return rc;	XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);	if (cmp) {		/* unpin the leaf page */		XT_PUTPAGE(mp);		return -ENOENT;	}	/*	 * delete the entry from the leaf page	 */	nextindex = le16_to_cpu(p->header.nextindex);	p->header.nextindex =	    cpu_to_le16(le16_to_cpu(p->header.nextindex) - 1);	/*	 * if the leaf page bocome empty, free the page	 */	if (p->header.nextindex == cpu_to_le16(XTENTRYSTART))		return (xtDeleteUp(tid, ip, mp, p, &btstack));	BT_MARK_DIRTY(mp, ip);	/*	 * acquire a transaction lock on the leaf page;	 *	 * action:xad deletion;	 */	tlck = txLock(tid, ip, mp, tlckXTREE);	xtlck = (struct xtlock *) & tlck->lock;	xtlck->lwm.offset =	    (xtlck->lwm.offset) ? min(index, xtlck->lwm.offset) : index;	/* if delete from middle, shift left/compact the remaining entries */	if (index < nextindex - 1)		memmove(&p->xad[index], &p->xad[index + 1],			(nextindex - index - 1) * sizeof(xad_t));	XT_PUTPAGE(mp);	return 0;}/* - TBD for defragmentaion/reorganization - * *      xtDeleteUp() * * function: *      free empty pages as propagating deletion up the tree * * parameter: * * return: */static intxtDeleteUp(tid_t tid, struct inode *ip,	   struct metapage * fmp, xtpage_t * fp, struct btstack * btstack){	int rc = 0;	struct metapage *mp;	xtpage_t *p;	int index, nextindex;	s64 xaddr;	int xlen;	struct btframe *parent;	struct tlock *tlck;	struct xtlock *xtlck;	/*	 * keep root leaf page which has become empty	 */	if (fp->header.flag & BT_ROOT) {		/* keep the root page */		fp->header.flag &= ~BT_INTERNAL;		fp->header.flag |= BT_LEAF;		fp->header.nextindex = cpu_to_le16(XTENTRYSTART);		/* XT_PUTPAGE(fmp); */		return 0;	}	/*	 * free non-root leaf page	 */	if ((rc = xtRelink(tid, ip, fp))) {		XT_PUTPAGE(fmp);		return rc;	}	xaddr = addressPXD(&fp->header.self);	xlen = lengthPXD(&fp->header.self);	/* free the page extent */	dbFree(ip, xaddr, (s64) xlen);	/* free the buffer page */	discard_metapage(fmp);	/*	 * propagate page deletion up the index tree	 *	 * If the delete from the parent page makes it empty,	 * continue all the way up the tree.	 * stop if the root page is reached (which is never deleted) or	 * if the entry deletion does not empty the page.	 */	while ((parent = BT_POP(btstack)) != NULL) {		/* get/pin the parent page <sp> */		XT_GETPAGE(ip, parent->bn, mp, PSIZE, p, rc);		if (rc)			return rc;		index = parent->index;		/* delete the entry for the freed child page from parent.		 */		nextindex = le16_to_cpu(p->header.nextindex);		/*		 * the parent has the single entry being deleted:		 * free the parent page which has become empty.		 */		if (nextindex == 1) {			if (p->header.flag & BT_ROOT) {				/* keep the root page */				p->header.flag &= ~BT_INTERNAL;				p->header.flag |= BT_LEAF;				p->header.nextindex =				    cpu_to_le16(XTENTRYSTART);				/* XT_PUTPAGE(mp); */				break;			} else {				/* free the parent page */				if ((rc = xtRelink(tid, ip, p)))					return rc;				xaddr = addressPXD(&p->header.self);				/* free the page extent */				dbFree(ip, xaddr,			

⌨️ 快捷键说明

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