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

📄 xfs_bmap_btree.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
{	return ((xfs_fileoff_t)r->l0 &		 XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;}xfs_exntst_txfs_bmbt_get_state(	xfs_bmbt_rec_host_t	*r){	int	ext_flag;	ext_flag = (int)((r->l0) >> (64 - BMBT_EXNTFLAG_BITLEN));	return xfs_extent_state(xfs_bmbt_get_blockcount(r),				ext_flag);}/* Endian flipping versions of the bmbt extraction functions */voidxfs_bmbt_disk_get_all(	xfs_bmbt_rec_t	*r,	xfs_bmbt_irec_t *s){	__xfs_bmbt_get_all(be64_to_cpu(r->l0), be64_to_cpu(r->l1), s);}/* * Extract the blockcount field from an on disk bmap extent record. */xfs_filblks_txfs_bmbt_disk_get_blockcount(	xfs_bmbt_rec_t	*r){	return (xfs_filblks_t)(be64_to_cpu(r->l1) & XFS_MASK64LO(21));}/* * Extract the startoff field from a disk format bmap extent record. */xfs_fileoff_txfs_bmbt_disk_get_startoff(	xfs_bmbt_rec_t	*r){	return ((xfs_fileoff_t)be64_to_cpu(r->l0) &		 XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;}/* * Increment cursor by one record at the level. * For nonzero levels the leaf-ward information is untouched. */int						/* error */xfs_bmbt_increment(	xfs_btree_cur_t		*cur,	int			level,	int			*stat)		/* success/failure */{	xfs_bmbt_block_t	*block;	xfs_buf_t		*bp;	int			error;		/* error return value */	xfs_fsblock_t		fsbno;	int			lev;	xfs_mount_t		*mp;	xfs_trans_t		*tp;	XFS_BMBT_TRACE_CURSOR(cur, ENTRY);	XFS_BMBT_TRACE_ARGI(cur, level);	ASSERT(level < cur->bc_nlevels);	if (level < cur->bc_nlevels - 1)		xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA);	block = xfs_bmbt_get_block(cur, level, &bp);#ifdef DEBUG	if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {		XFS_BMBT_TRACE_CURSOR(cur, ERROR);		return error;	}#endif	if (++cur->bc_ptrs[level] <= be16_to_cpu(block->bb_numrecs)) {		XFS_BMBT_TRACE_CURSOR(cur, EXIT);		*stat = 1;		return 0;	}	if (be64_to_cpu(block->bb_rightsib) == NULLDFSBNO) {		XFS_BMBT_TRACE_CURSOR(cur, EXIT);		*stat = 0;		return 0;	}	for (lev = level + 1; lev < cur->bc_nlevels; lev++) {		block = xfs_bmbt_get_block(cur, lev, &bp);#ifdef DEBUG		if ((error = xfs_btree_check_lblock(cur, block, lev, bp))) {			XFS_BMBT_TRACE_CURSOR(cur, ERROR);			return error;		}#endif		if (++cur->bc_ptrs[lev] <= be16_to_cpu(block->bb_numrecs))			break;		if (lev < cur->bc_nlevels - 1)			xfs_btree_readahead(cur, lev, XFS_BTCUR_RIGHTRA);	}	if (lev == cur->bc_nlevels) {		XFS_BMBT_TRACE_CURSOR(cur, EXIT);		*stat = 0;		return 0;	}	tp = cur->bc_tp;	mp = cur->bc_mp;	for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) {		fsbno = be64_to_cpu(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur));		if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp,				XFS_BMAP_BTREE_REF))) {			XFS_BMBT_TRACE_CURSOR(cur, ERROR);			return error;		}		lev--;		xfs_btree_setbuf(cur, lev, bp);		block = XFS_BUF_TO_BMBT_BLOCK(bp);		if ((error = xfs_btree_check_lblock(cur, block, lev, bp))) {			XFS_BMBT_TRACE_CURSOR(cur, ERROR);			return error;		}		cur->bc_ptrs[lev] = 1;	}	XFS_BMBT_TRACE_CURSOR(cur, EXIT);	*stat = 1;	return 0;}/* * Insert the current record at the point referenced by cur. */int					/* error */xfs_bmbt_insert(	xfs_btree_cur_t	*cur,	int		*stat)		/* success/failure */{	int		error;		/* error return value */	int		i;	int		level;	xfs_fsblock_t	nbno;	xfs_btree_cur_t	*ncur;	xfs_bmbt_rec_t	nrec;	xfs_btree_cur_t	*pcur;	XFS_BMBT_TRACE_CURSOR(cur, ENTRY);	level = 0;	nbno = NULLFSBLOCK;	xfs_bmbt_disk_set_all(&nrec, &cur->bc_rec.b);	ncur = NULL;	pcur = cur;	do {		if ((error = xfs_bmbt_insrec(pcur, level++, &nbno, &nrec, &ncur,				&i))) {			if (pcur != cur)				xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR);			XFS_BMBT_TRACE_CURSOR(cur, ERROR);			return error;		}		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);		if (pcur != cur && (ncur || nbno == NULLFSBLOCK)) {			cur->bc_nlevels = pcur->bc_nlevels;			cur->bc_private.b.allocated +=				pcur->bc_private.b.allocated;			pcur->bc_private.b.allocated = 0;			ASSERT((cur->bc_private.b.firstblock != NULLFSBLOCK) ||			       (cur->bc_private.b.ip->i_d.di_flags &				XFS_DIFLAG_REALTIME));			cur->bc_private.b.firstblock =				pcur->bc_private.b.firstblock;			ASSERT(cur->bc_private.b.flist ==			       pcur->bc_private.b.flist);			xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR);		}		if (ncur) {			pcur = ncur;			ncur = NULL;		}	} while (nbno != NULLFSBLOCK);	XFS_BMBT_TRACE_CURSOR(cur, EXIT);	*stat = i;	return 0;error0:	XFS_BMBT_TRACE_CURSOR(cur, ERROR);	return error;}/* * Log fields from the btree block header. */voidxfs_bmbt_log_block(	xfs_btree_cur_t		*cur,	xfs_buf_t		*bp,	int			fields){	int			first;	int			last;	xfs_trans_t		*tp;	static const short	offsets[] = {		offsetof(xfs_bmbt_block_t, bb_magic),		offsetof(xfs_bmbt_block_t, bb_level),		offsetof(xfs_bmbt_block_t, bb_numrecs),		offsetof(xfs_bmbt_block_t, bb_leftsib),		offsetof(xfs_bmbt_block_t, bb_rightsib),		sizeof(xfs_bmbt_block_t)	};	XFS_BMBT_TRACE_CURSOR(cur, ENTRY);	XFS_BMBT_TRACE_ARGBI(cur, bp, fields);	tp = cur->bc_tp;	if (bp) {		xfs_btree_offsets(fields, offsets, XFS_BB_NUM_BITS, &first,				  &last);		xfs_trans_log_buf(tp, bp, first, last);	} else		xfs_trans_log_inode(tp, cur->bc_private.b.ip,			XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));	XFS_BMBT_TRACE_CURSOR(cur, EXIT);}/* * Log record values from the btree block. */voidxfs_bmbt_log_recs(	xfs_btree_cur_t		*cur,	xfs_buf_t		*bp,	int			rfirst,	int			rlast){	xfs_bmbt_block_t	*block;	int			first;	int			last;	xfs_bmbt_rec_t		*rp;	xfs_trans_t		*tp;	XFS_BMBT_TRACE_CURSOR(cur, ENTRY);	XFS_BMBT_TRACE_ARGBII(cur, bp, rfirst, rlast);	ASSERT(bp);	tp = cur->bc_tp;	block = XFS_BUF_TO_BMBT_BLOCK(bp);	rp = XFS_BMAP_REC_DADDR(block, 1, cur);	first = (int)((xfs_caddr_t)&rp[rfirst - 1] - (xfs_caddr_t)block);	last = (int)(((xfs_caddr_t)&rp[rlast] - 1) - (xfs_caddr_t)block);	xfs_trans_log_buf(tp, bp, first, last);	XFS_BMBT_TRACE_CURSOR(cur, EXIT);}int					/* error */xfs_bmbt_lookup_eq(	xfs_btree_cur_t	*cur,	xfs_fileoff_t	off,	xfs_fsblock_t	bno,	xfs_filblks_t	len,	int		*stat)		/* success/failure */{	cur->bc_rec.b.br_startoff = off;	cur->bc_rec.b.br_startblock = bno;	cur->bc_rec.b.br_blockcount = len;	return xfs_bmbt_lookup(cur, XFS_LOOKUP_EQ, stat);}int					/* error */xfs_bmbt_lookup_ge(	xfs_btree_cur_t	*cur,	xfs_fileoff_t	off,	xfs_fsblock_t	bno,	xfs_filblks_t	len,	int		*stat)		/* success/failure */{	cur->bc_rec.b.br_startoff = off;	cur->bc_rec.b.br_startblock = bno;	cur->bc_rec.b.br_blockcount = len;	return xfs_bmbt_lookup(cur, XFS_LOOKUP_GE, stat);}/* * Give the bmap btree a new root block.  Copy the old broot contents * down into a real block and make the broot point to it. */int						/* error */xfs_bmbt_newroot(	xfs_btree_cur_t		*cur,		/* btree cursor */	int			*logflags,	/* logging flags for inode */	int			*stat)		/* return status - 0 fail */{	xfs_alloc_arg_t		args;		/* allocation arguments */	xfs_bmbt_block_t	*block;		/* bmap btree block */	xfs_buf_t		*bp;		/* buffer for block */	xfs_bmbt_block_t	*cblock;	/* child btree block */	xfs_bmbt_key_t		*ckp;		/* child key pointer */	xfs_bmbt_ptr_t		*cpp;		/* child ptr pointer */	int			error;		/* error return code */#ifdef DEBUG	int			i;		/* loop counter */#endif	xfs_bmbt_key_t		*kp;		/* pointer to bmap btree key */	int			level;		/* btree level */	xfs_bmbt_ptr_t		*pp;		/* pointer to bmap block addr */	XFS_BMBT_TRACE_CURSOR(cur, ENTRY);	level = cur->bc_nlevels - 1;	block = xfs_bmbt_get_block(cur, level, &bp);	/*	 * Copy the root into a real block.	 */	args.mp = cur->bc_mp;	pp = XFS_BMAP_PTR_IADDR(block, 1, cur);	args.tp = cur->bc_tp;	args.fsbno = cur->bc_private.b.firstblock;	args.mod = args.minleft = args.alignment = args.total = args.isfl =		args.userdata = args.minalignslop = 0;	args.minlen = args.maxlen = args.prod = 1;	args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;	args.firstblock = args.fsbno;	if (args.fsbno == NULLFSBLOCK) {#ifdef DEBUG		if ((error = xfs_btree_check_lptr_disk(cur, *pp, level))) {			XFS_BMBT_TRACE_CURSOR(cur, ERROR);			return error;		}#endif		args.fsbno = be64_to_cpu(*pp);		args.type = XFS_ALLOCTYPE_START_BNO;	} else		args.type = XFS_ALLOCTYPE_NEAR_BNO;	if ((error = xfs_alloc_vextent(&args))) {		XFS_BMBT_TRACE_CURSOR(cur, ERROR);		return error;	}	if (args.fsbno == NULLFSBLOCK) {		XFS_BMBT_TRACE_CURSOR(cur, EXIT);		*stat = 0;		return 0;	}	ASSERT(args.len == 1);	cur->bc_private.b.firstblock = args.fsbno;	cur->bc_private.b.allocated++;	cur->bc_private.b.ip->i_d.di_nblocks++;	XFS_TRANS_MOD_DQUOT_BYINO(args.mp, args.tp, cur->bc_private.b.ip,			  XFS_TRANS_DQ_BCOUNT, 1L);	bp = xfs_btree_get_bufl(args.mp, cur->bc_tp, args.fsbno, 0);	cblock = XFS_BUF_TO_BMBT_BLOCK(bp);	*cblock = *block;	be16_add(&block->bb_level, 1);	block->bb_numrecs = cpu_to_be16(1);	cur->bc_nlevels++;	cur->bc_ptrs[level + 1] = 1;	kp = XFS_BMAP_KEY_IADDR(block, 1, cur);	ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur);	memcpy(ckp, kp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*kp));	cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur);#ifdef DEBUG	for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) {		if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) {			XFS_BMBT_TRACE_CURSOR(cur, ERROR);			return error;		}	}#endif	memcpy(cpp, pp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*pp));#ifdef DEBUG	if ((error = xfs_btree_check_lptr(cur, args.fsbno, level))) {		XFS_BMBT_TRACE_CURSOR(cur, ERROR);		return error;	}#endif	*pp = cpu_to_be64(args.fsbno);	xfs_iroot_realloc(cur->bc_private.b.ip, 1 - be16_to_cpu(cblock->bb_numrecs),		cur->bc_private.b.whichfork);	xfs_btree_setbuf(cur, level, bp);	/*	 * Do all this logging at the end so that	 * the root is at the right level.	 */	xfs_bmbt_log_block(cur, bp, XFS_BB_ALL_BITS);	xfs_bmbt_log_keys(cur, bp, 1, be16_to_cpu(cblock->bb_numrecs));	xfs_bmbt_log_ptrs(cur, bp, 1, be16_to_cpu(cblock->bb_numrecs));	XFS_BMBT_TRACE_CURSOR(cur, EXIT);	*logflags |=		XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork);	*stat = 1;	return 0;}/* * Set all the fields in a bmap extent record from the arguments. */voidxfs_bmbt_set_allf(	xfs_bmbt_rec_host_t	*r,	xfs_fileoff_t		startoff,	xfs_fsblock_t		startblock,	xfs_filblks_t		blockcount,	xfs_exntst_t		state){	int		extent_flag = (state == XFS_EXT_NORM) ? 0 : 1;	ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN);	ASSERT((startoff & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);	ASSERT((blockcount & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);#if XFS_BIG_BLKNOS	ASSERT((startblock & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0);	r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |		((xfs_bmbt_rec_base_t)startoff << 9) |		((xfs_bmbt_rec_base_t)startblock >> 43);	r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) |		((xfs_bmbt_rec_base_t)blockcount &		(xfs_bmbt_rec_base_t)XFS_MASK64LO(21));#else	/* !XFS_BIG_BLKNOS */	if (ISNULLSTARTBLOCK(startblock)) {		r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |			((xfs_bmbt_rec_base_t)startoff << 9) |			 (xfs_bmbt_rec_base_t)XFS_MASK64LO(9);		r->l1 = XFS_MASK64HI(11) |			  ((xfs_bmbt_rec_base_t)startblock << 21) |			  ((xfs_bmbt_rec_base_t)blockcount &			   (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));	} else {		r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |			((xfs_bmbt_rec_base_t)startoff << 9);		r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) |			 ((xfs_bmbt_rec_base_t)blockcount &			 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));	}#endif	/* XFS_BIG_BLKNOS */}/* * Set all the fields in a bmap extent record from the uncompressed form. */voidxfs_bmbt_set_all(	xfs_bmbt_rec_host_t *r,	xfs_bmbt_irec_t	*s){	xfs_bmbt_set_allf(r, s->br_startoff, s->br_startblock,			     s->br_blockcount, s->br_state);}/* * Set all the fields in a disk format bmap extent record from the arguments. */voidxfs_bmbt_disk_set_allf(	xfs_bmbt_rec_t		*r,	xfs_fileoff_t		startoff,	xfs_fsblock_t		startblock,	xfs_filblks_t		blockcount,	xfs_exntst_t		state){	int			extent_flag = (state == XFS_EXT_NORM) ? 0 : 1;	ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN);	ASSERT((startoff & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);	ASSERT((blockcount & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);#if XFS_BIG_BLKNOS	ASSERT((startblock & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0);	r->l0 = cpu_to_be64(		((xfs_bmbt_rec_base_t)extent_flag << 63) |		 ((xfs_bmbt_rec_base_t)startoff << 9) |		 ((xfs_bmbt_rec_base_t)startblock >> 43));	r->l1 = cpu_to_be64(		((xfs_bmbt_rec_base_t)startblock << 21) |		 ((xfs_bmbt_rec_base_t)blockcount &		  (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));#else	/* !XFS_BIG_BLKNOS */	if (ISNULLSTARTBLOCK(startblock)) {		r->l0 = cpu_to_be64(			((xfs_bmbt_rec_base_t)extent_flag << 63) |			 ((xfs

⌨️ 快捷键说明

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