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

📄 xfs_ialloc_btree.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));		keyp->ir_startino = rrp->ir_startino;	}	/*	 * Find the left block number by looking in the buffer.	 * Adjust numrecs, sibling pointers.	 */	be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));	right->bb_rightsib = left->bb_rightsib;	left->bb_rightsib = cpu_to_be32(args.agbno);	right->bb_leftsib = cpu_to_be32(lbno);	xfs_inobt_log_block(args.tp, rbp, XFS_BB_ALL_BITS);	xfs_inobt_log_block(args.tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);	/*	 * If there's a block to the new block's right, make that block	 * point back to right instead of to left.	 */	if (be32_to_cpu(right->bb_rightsib) != NULLAGBLOCK) {		xfs_inobt_block_t	*rrblock;	/* rr btree block */		xfs_buf_t		*rrbp;		/* buffer for rrblock */		if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno,				be32_to_cpu(right->bb_rightsib), 0, &rrbp,				XFS_INO_BTREE_REF)))			return error;		rrblock = XFS_BUF_TO_INOBT_BLOCK(rrbp);		if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp)))			return error;		rrblock->bb_leftsib = cpu_to_be32(args.agbno);		xfs_inobt_log_block(args.tp, rrbp, XFS_BB_LEFTSIB);	}	/*	 * If the cursor is really in the right block, move it there.	 * If it's just pointing past the last entry in left, then we'll	 * insert there, so don't change anything in that case.	 */	if (cur->bc_ptrs[level] > be16_to_cpu(left->bb_numrecs) + 1) {		xfs_btree_setbuf(cur, level, rbp);		cur->bc_ptrs[level] -= be16_to_cpu(left->bb_numrecs);	}	/*	 * If there are more levels, we'll need another cursor which refers	 * the right block, no matter where this cursor was.	 */	if (level + 1 < cur->bc_nlevels) {		if ((error = xfs_btree_dup_cursor(cur, curp)))			return error;		(*curp)->bc_ptrs[level + 1]++;	}	*bnop = args.agbno;	*stat = 1;	return 0;}/* * Update keys at all levels from here to the root along the cursor's path. */STATIC int				/* error */xfs_inobt_updkey(	xfs_btree_cur_t		*cur,	/* btree cursor */	xfs_inobt_key_t		*keyp,	/* new key value to update to */	int			level)	/* starting level for update */{	int			ptr;	/* index of key in block */	/*	 * Go up the tree from this level toward the root.	 * At each level, update the key value to the value input.	 * Stop when we reach a level where the cursor isn't pointing	 * at the first entry in the block.	 */	for (ptr = 1; ptr == 1 && level < cur->bc_nlevels; level++) {		xfs_buf_t		*bp;	/* buffer for block */		xfs_inobt_block_t	*block;	/* btree block */#ifdef DEBUG		int			error;	/* error return value */#endif		xfs_inobt_key_t		*kp;	/* ptr to btree block keys */		bp = cur->bc_bufs[level];		block = XFS_BUF_TO_INOBT_BLOCK(bp);#ifdef DEBUG		if ((error = xfs_btree_check_sblock(cur, block, level, bp)))			return error;#endif		ptr = cur->bc_ptrs[level];		kp = XFS_INOBT_KEY_ADDR(block, ptr, cur);		*kp = *keyp;		xfs_inobt_log_keys(cur, bp, ptr, ptr);	}	return 0;}/* * Externally visible routines. *//* * Decrement cursor by one record at the level. * For nonzero levels the leaf-ward information is untouched. */int					/* error */xfs_inobt_decrement(	xfs_btree_cur_t		*cur,	/* btree cursor */	int			level,	/* level in btree, 0 is leaf */	int			*stat)	/* success/failure */{	xfs_inobt_block_t	*block;	/* btree block */	int			error;	int			lev;	/* btree level */	ASSERT(level < cur->bc_nlevels);	/*	 * Read-ahead to the left at this level.	 */	xfs_btree_readahead(cur, level, XFS_BTCUR_LEFTRA);	/*	 * Decrement the ptr at this level.  If we're still in the block	 * then we're done.	 */	if (--cur->bc_ptrs[level] > 0) {		*stat = 1;		return 0;	}	/*	 * Get a pointer to the btree block.	 */	block = XFS_BUF_TO_INOBT_BLOCK(cur->bc_bufs[level]);#ifdef DEBUG	if ((error = xfs_btree_check_sblock(cur, block, level,			cur->bc_bufs[level])))		return error;#endif	/*	 * If we just went off the left edge of the tree, return failure.	 */	if (be32_to_cpu(block->bb_leftsib) == NULLAGBLOCK) {		*stat = 0;		return 0;	}	/*	 * March up the tree decrementing pointers.	 * Stop when we don't go off the left edge of a block.	 */	for (lev = level + 1; lev < cur->bc_nlevels; lev++) {		if (--cur->bc_ptrs[lev] > 0)			break;		/*		 * Read-ahead the left block, we're going to read it		 * in the next loop.		 */		xfs_btree_readahead(cur, lev, XFS_BTCUR_LEFTRA);	}	/*	 * If we went off the root then we are seriously confused.	 */	ASSERT(lev < cur->bc_nlevels);	/*	 * Now walk back down the tree, fixing up the cursor's buffer	 * pointers and key numbers.	 */	for (block = XFS_BUF_TO_INOBT_BLOCK(cur->bc_bufs[lev]); lev > level; ) {		xfs_agblock_t	agbno;	/* block number of btree block */		xfs_buf_t	*bp;	/* buffer containing btree block */		agbno = be32_to_cpu(*XFS_INOBT_PTR_ADDR(block, cur->bc_ptrs[lev], cur));		if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,				cur->bc_private.i.agno, agbno, 0, &bp,				XFS_INO_BTREE_REF)))			return error;		lev--;		xfs_btree_setbuf(cur, lev, bp);		block = XFS_BUF_TO_INOBT_BLOCK(bp);		if ((error = xfs_btree_check_sblock(cur, block, lev, bp)))			return error;		cur->bc_ptrs[lev] = be16_to_cpu(block->bb_numrecs);	}	*stat = 1;	return 0;}/* * Delete the record pointed to by cur. * The cursor refers to the place where the record was (could be inserted) * when the operation returns. */int					/* error */xfs_inobt_delete(	xfs_btree_cur_t	*cur,		/* btree cursor */	int		*stat)		/* success/failure */{	int		error;	int		i;		/* result code */	int		level;		/* btree level */	/*	 * Go up the tree, starting at leaf level.	 * If 2 is returned then a join was done; go to the next level.	 * Otherwise we are done.	 */	for (level = 0, i = 2; i == 2; level++) {		if ((error = xfs_inobt_delrec(cur, level, &i)))			return error;	}	if (i == 0) {		for (level = 1; level < cur->bc_nlevels; level++) {			if (cur->bc_ptrs[level] == 0) {				if ((error = xfs_inobt_decrement(cur, level, &i)))					return error;				break;			}		}	}	*stat = i;	return 0;}/* * Get the data from the pointed-to record. */int					/* error */xfs_inobt_get_rec(	xfs_btree_cur_t		*cur,	/* btree cursor */	xfs_agino_t		*ino,	/* output: starting inode of chunk */	__int32_t		*fcnt,	/* output: number of free inodes */	xfs_inofree_t		*free,	/* output: free inode mask */	int			*stat)	/* output: success/failure */{	xfs_inobt_block_t	*block;	/* btree block */	xfs_buf_t		*bp;	/* buffer containing btree block */#ifdef DEBUG	int			error;	/* error return value */#endif	int			ptr;	/* record number */	xfs_inobt_rec_t		*rec;	/* record data */	bp = cur->bc_bufs[0];	ptr = cur->bc_ptrs[0];	block = XFS_BUF_TO_INOBT_BLOCK(bp);#ifdef DEBUG	if ((error = xfs_btree_check_sblock(cur, block, 0, bp)))		return error;#endif	/*	 * Off the right end or left end, return failure.	 */	if (ptr > be16_to_cpu(block->bb_numrecs) || ptr <= 0) {		*stat = 0;		return 0;	}	/*	 * Point to the record and extract its data.	 */	rec = XFS_INOBT_REC_ADDR(block, ptr, cur);	*ino = be32_to_cpu(rec->ir_startino);	*fcnt = be32_to_cpu(rec->ir_freecount);	*free = be64_to_cpu(rec->ir_free);	*stat = 1;	return 0;}/* * Increment cursor by one record at the level. * For nonzero levels the leaf-ward information is untouched. */int					/* error */xfs_inobt_increment(	xfs_btree_cur_t		*cur,	/* btree cursor */	int			level,	/* level in btree, 0 is leaf */	int			*stat)	/* success/failure */{	xfs_inobt_block_t	*block;	/* btree block */	xfs_buf_t		*bp;	/* buffer containing btree block */	int			error;	/* error return value */	int			lev;	/* btree level */	ASSERT(level < cur->bc_nlevels);	/*	 * Read-ahead to the right at this level.	 */	xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA);	/*	 * Get a pointer to the btree block.	 */	bp = cur->bc_bufs[level];	block = XFS_BUF_TO_INOBT_BLOCK(bp);#ifdef DEBUG	if ((error = xfs_btree_check_sblock(cur, block, level, bp)))		return error;#endif	/*	 * Increment the ptr at this level.  If we're still in the block	 * then we're done.	 */	if (++cur->bc_ptrs[level] <= be16_to_cpu(block->bb_numrecs)) {		*stat = 1;		return 0;	}	/*	 * If we just went off the right edge of the tree, return failure.	 */	if (be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK) {		*stat = 0;		return 0;	}	/*	 * March up the tree incrementing pointers.	 * Stop when we don't go off the right edge of a block.	 */	for (lev = level + 1; lev < cur->bc_nlevels; lev++) {		bp = cur->bc_bufs[lev];		block = XFS_BUF_TO_INOBT_BLOCK(bp);#ifdef DEBUG		if ((error = xfs_btree_check_sblock(cur, block, lev, bp)))			return error;#endif		if (++cur->bc_ptrs[lev] <= be16_to_cpu(block->bb_numrecs))			break;		/*		 * Read-ahead the right block, we're going to read it		 * in the next loop.		 */		xfs_btree_readahead(cur, lev, XFS_BTCUR_RIGHTRA);	}	/*	 * If we went off the root then we are seriously confused.	 */	ASSERT(lev < cur->bc_nlevels);	/*	 * Now walk back down the tree, fixing up the cursor's buffer	 * pointers and key numbers.	 */	for (bp = cur->bc_bufs[lev], block = XFS_BUF_TO_INOBT_BLOCK(bp);	     lev > level; ) {		xfs_agblock_t	agbno;	/* block number of btree block */		agbno = be32_to_cpu(*XFS_INOBT_PTR_ADDR(block, cur->bc_ptrs[lev], cur));		if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,				cur->bc_private.i.agno, agbno, 0, &bp,				XFS_INO_BTREE_REF)))			return error;		lev--;		xfs_btree_setbuf(cur, lev, bp);		block = XFS_BUF_TO_INOBT_BLOCK(bp);		if ((error = xfs_btree_check_sblock(cur, block, lev, bp)))			return error;		cur->bc_ptrs[lev] = 1;	}	*stat = 1;	return 0;}/* * Insert the current record at the point referenced by cur. * The cursor may be inconsistent on return if splits have been done. */int					/* error */xfs_inobt_insert(	xfs_btree_cur_t	*cur,		/* btree cursor */	int		*stat)		/* success/failure */{	int		error;		/* error return value */	int		i;		/* result value, 0 for failure */	int		level;		/* current level number in btree */	xfs_agblock_t	nbno;		/* new block number (split result) */	xfs_btree_cur_t	*ncur;		/* new cursor (split result) */	xfs_inobt_rec_t	nrec;		/* record being inserted this level */	xfs_btree_cur_t	*pcur;		/* previous level's cursor */	level = 0;	nbno = NULLAGBLOCK;	nrec.ir_startino = cpu_to_be32(cur->bc_rec.i.ir_startino);	nrec.ir_freecount = cpu_to_be32(cur->bc_rec.i.ir_freecount);	nrec.ir_free = cpu_to_be64(cur->bc_rec.i.ir_free);	ncur = NULL;	pcur = cur;	/*	 * Loop going up the tree, starting at the leaf level.	 * Stop when we don't get a split block, that must mean that	 * the insert is finished with this level.	 */	do {		/*		 * Insert nrec/nbno into this level of the tree.		 * Note if we fail, nbno will be null.		 */		if ((error = xfs_inobt_insrec(pcur, level++, &nbno, &nrec, &ncur,				&i))) {			if (pcur != cur)				xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR);			return error;		}		/*		 * See if the cursor we just used is trash.		 * Can't trash the caller's cursor, but otherwise we should		 * if ncur is a new cursor or we're about to be done.		 */		if (pcur != cur && (ncur || nbno == NULLAGBLOCK)) {			cur->bc_nlevels = pcur->bc_nlevels;			xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR);		}		/*		 * If we got a new cursor, switch to it.		 */		if (ncur) {			pcur = ncur;			ncur = NULL;		}	} while (nbno != NULLAGBLOCK);	*stat = i;	return 0;}/* * Lookup the record equal to ino in the btree given by cur. */int					/* error */xfs_inobt_lookup_eq(	xfs_btree_cur_t	*cur,		/* btree cursor */	xfs_agino_t	ino,		/* starting inode of chunk */	__int32_t	fcnt,		/* free inode count */	xfs_inofree_t	free,		/* free inode mask */	int		*stat)		/* success/failure */{	cur->bc_rec.i.ir_startino = ino;	cur->bc_rec.i.ir_freecount = fcnt;	cur->bc_rec.i.ir_free = free;	return xfs_inobt_lookup(cur, XFS_LOOKUP_EQ, stat);}/* * Lookup the first record greater than or equal to ino * in the btree given by cur. */int					/* error */xfs_inobt_lookup_ge(	xfs_btree_cur_t	*cur,		/* btree cursor */	xfs_agino_t	ino,		/* starting inode of chunk */	__int32_t	fcnt,		/* free inode count */	xfs_inofree_t	free,		/* free inode mask */	int		*stat)		/* success/failure */{	cur->bc_rec.i.ir_startino = ino;	cur->bc_rec.i.ir_freecount = fcnt;	cur->bc_rec.i.ir_free = free;	return xfs_inobt_lookup(cur, XFS_LOOKUP_GE, stat);}/* * Lookup the first record less than or equal to ino * in the btree given by cur. */int					/* error */xfs_inobt_lookup_le(	xfs_btree_cur_t	*cur,		/* btree cursor */	xfs_agino_t	ino,		/* starting inode of chunk */	__int32_t	fcnt,		/* free inode count */	xfs_inofree_t	free,		/* free inode mask */	int		*stat)		/* success/failure */{	cur->bc_rec.i.ir_startino = ino;	cur->bc_rec.i.ir_freecount = fcnt;	cur->bc_rec.i.ir_free = free;	return xfs_inobt_lookup(cur, XFS_LOOKUP_LE, stat);}/* * Update the record referred to by cur, to the value given * by [ino, fcnt, free]. * This either works (return 0) or gets an EFSCORRUPTED error. */int					/* error */xfs_inobt_update(	xfs_btree_cur_t		*cur,	/* btree cursor */	xfs_agino_t		ino,	/* starting inode of chunk */	__int32_t		fcnt,	/* free inode count */	xfs_inofree_t		free)	/* free inode mask */{	xfs_inobt_block_t	*block;	/* btree block to update */	xfs_buf_t		*bp;	/* buffer containing btree block */	int			error;	/* error return value */	int			ptr;	/* current record number (updating) */	xfs_inobt_rec_t		*rp;	/* pointer to updated record */	/*	 * Pick up the current block.	 */	bp = cur->bc_bufs[0];	block = XFS_BUF_TO_INOBT_BLOCK(bp);#ifdef DEBUG	if ((error = xfs_btree_check_sblock(cur, block, 0, bp)))		return error;#endif	/*	 * Get the address of the rec to be updated.	 */	ptr = cur->bc_ptrs[0];	rp = XFS_INOBT_REC_ADDR(block, ptr, cur);	/*	 * Fill in the new contents and log them.	 */	rp->ir_startino = cpu_to_be32(ino);	rp->ir_freecount = cpu_to_be32(fcnt);	rp->ir_free = cpu_to_be64(free);	xfs_inobt_log_recs(cur, bp, ptr, ptr);	/*	 * Updating first record in leaf. Pass new key value up to our parent.	 */	if (ptr == 1) {		xfs_inobt_key_t	key;	/* key containing [ino] */		key.ir_startino = cpu_to_be32(ino);		if ((error = xfs_inobt_updkey(cur, &key, 1)))			return error;	}	return 0;}

⌨️ 快捷键说明

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