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

📄 xfs_rtalloc.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			if (i >= 0) {				/*				 * Try to allocate an extent starting in				 * this block.				 */				error = xfs_rtallocate_extent_block(mp, tp,					bbno + i, minlen, maxlen, len, &n, rbpp,					rsb, prod, &r);				if (error) {					return error;				}				/*				 * If it worked, return it.				 */				if (r != NULLRTBLOCK) {					*rtblock = r;					return 0;				}			}			/*			 * On the negative side of the starting location.			 */			else {		/* i < 0 */				/*				 * Loop backwards through the bitmap blocks from				 * the starting point-1 up to where we are now.				 * There should be an extent which ends in this				 * bitmap block and is long enough.				 */				for (j = -1; j > i; j--) {					/*					 * Grab the summary information for					 * this bitmap block.					 */					error = xfs_rtany_summary(mp, tp,						log2len, mp->m_rsumlevels - 1,						bbno + j, rbpp, rsb, &any);					if (error) {						return error;					}					/*					 * If there's no extent given in the					 * summary that means the extent we					 * found must carry over from an					 * earlier block.  If there is an					 * extent given, we've already tried					 * that allocation, don't do it again.					 */					if (any)						continue;					error = xfs_rtallocate_extent_block(mp,						tp, bbno + j, minlen, maxlen,						len, &n, rbpp, rsb, prod, &r);					if (error) {						return error;					}					/*					 * If it works, return the extent.					 */					if (r != NULLRTBLOCK) {						*rtblock = r;						return 0;					}				}				/*				 * There weren't intervening bitmap blocks				 * with a long enough extent, or the				 * allocation didn't work for some reason				 * (i.e. it's a little * too short).				 * Try to allocate from the summary block				 * that we found.				 */				error = xfs_rtallocate_extent_block(mp, tp,					bbno + i, minlen, maxlen, len, &n, rbpp,					rsb, prod, &r);				if (error) {					return error;				}				/*				 * If it works, return the extent.				 */				if (r != NULLRTBLOCK) {					*rtblock = r;					return 0;				}			}		}		/*		 * Loop control.  If we were on the positive side, and there's		 * still more blocks on the negative side, go there.		 */		if (i > 0 && (int)bbno - i >= 0)			i = -i;		/*		 * If positive, and no more negative, but there are more		 * positive, go there.		 */		else if (i > 0 && (int)bbno + i < mp->m_sb.sb_rbmblocks - 1)			i++;		/*		 * If negative or 0 (just started), and there are positive		 * blocks to go, go there.  The 0 case moves to block 1.		 */		else if (i <= 0 && (int)bbno - i < mp->m_sb.sb_rbmblocks - 1)			i = 1 - i;		/*		 * If negative or 0 and there are more negative blocks,		 * go there.		 */		else if (i <= 0 && (int)bbno + i > 0)			i--;		/*		 * Must be done.  Return failure.		 */		else			break;	}	*rtblock = NULLRTBLOCK;	return 0;}/* * Allocate an extent of length minlen<=len<=maxlen, with no position * specified.  If we don't get maxlen then use prod to trim * the length, if given.  The lengths are all in rtextents. */STATIC int				/* error */xfs_rtallocate_extent_size(	xfs_mount_t	*mp,		/* file system mount point */	xfs_trans_t	*tp,		/* transaction pointer */	xfs_extlen_t	minlen,		/* minimum length to allocate */	xfs_extlen_t	maxlen,		/* maximum length to allocate */	xfs_extlen_t	*len,		/* out: actual length allocated */	xfs_buf_t	**rbpp,		/* in/out: summary block buffer */	xfs_fsblock_t	*rsb,		/* in/out: summary block number */	xfs_extlen_t	prod,		/* extent product factor */	xfs_rtblock_t	*rtblock)	/* out: start block allocated */{	int		error;		/* error value */	int		i;		/* bitmap block number */	int		l;		/* level number (loop control) */	xfs_rtblock_t	n;		/* next block to be tried */	xfs_rtblock_t	r;		/* result block number */	xfs_suminfo_t	sum;		/* summary information for extents */	ASSERT(minlen % prod == 0 && maxlen % prod == 0);	/*	 * Loop over all the levels starting with maxlen.	 * At each level, look at all the bitmap blocks, to see if there	 * are extents starting there that are long enough (>= maxlen).	 * Note, only on the initial level can the allocation fail if	 * the summary says there's an extent.	 */	for (l = xfs_highbit32(maxlen); l < mp->m_rsumlevels; l++) {		/*		 * Loop over all the bitmap blocks.		 */		for (i = 0; i < mp->m_sb.sb_rbmblocks; i++) {			/*			 * Get the summary for this level/block.			 */			error = xfs_rtget_summary(mp, tp, l, i, rbpp, rsb,				&sum);			if (error) {				return error;			}			/*			 * Nothing there, on to the next block.			 */			if (!sum)				continue;			/*			 * Try allocating the extent.			 */			error = xfs_rtallocate_extent_block(mp, tp, i, maxlen,				maxlen, len, &n, rbpp, rsb, prod, &r);			if (error) {				return error;			}			/*			 * If it worked, return that.			 */			if (r != NULLRTBLOCK) {				*rtblock = r;				return 0;			}			/*			 * If the "next block to try" returned from the			 * allocator is beyond the next bitmap block,			 * skip to that bitmap block.			 */			if (XFS_BITTOBLOCK(mp, n) > i + 1)				i = XFS_BITTOBLOCK(mp, n) - 1;		}	}	/*	 * Didn't find any maxlen blocks.  Try smaller ones, unless	 * we're asking for a fixed size extent.	 */	if (minlen > --maxlen) {		*rtblock = NULLRTBLOCK;		return 0;	}	/*	 * Loop over sizes, from maxlen down to minlen.	 * This time, when we do the allocations, allow smaller ones	 * to succeed.	 */	for (l = xfs_highbit32(maxlen); l >= xfs_highbit32(minlen); l--) {		/*		 * Loop over all the bitmap blocks, try an allocation		 * starting in that block.		 */		for (i = 0; i < mp->m_sb.sb_rbmblocks; i++) {			/*			 * Get the summary information for this level/block.			 */			error =	xfs_rtget_summary(mp, tp, l, i, rbpp, rsb,						  &sum);			if (error) {				return error;			}			/*			 * If nothing there, go on to next.			 */			if (!sum)				continue;			/*			 * Try the allocation.  Make sure the specified			 * minlen/maxlen are in the possible range for			 * this summary level.			 */			error = xfs_rtallocate_extent_block(mp, tp, i,					XFS_RTMAX(minlen, 1 << l),					XFS_RTMIN(maxlen, (1 << (l + 1)) - 1),					len, &n, rbpp, rsb, prod, &r);			if (error) {				return error;			}			/*			 * If it worked, return that extent.			 */			if (r != NULLRTBLOCK) {				*rtblock = r;				return 0;			}			/*			 * If the "next block to try" returned from the			 * allocator is beyond the next bitmap block,			 * skip to that bitmap block.			 */			if (XFS_BITTOBLOCK(mp, n) > i + 1)				i = XFS_BITTOBLOCK(mp, n) - 1;		}	}	/*	 * Got nothing, return failure.	 */	*rtblock = NULLRTBLOCK;	return 0;}/* * Mark an extent specified by start and len allocated. * Updates all the summary information as well as the bitmap. */STATIC int				/* error */xfs_rtallocate_range(	xfs_mount_t	*mp,		/* file system mount point */	xfs_trans_t	*tp,		/* transaction pointer */	xfs_rtblock_t	start,		/* start block to allocate */	xfs_extlen_t	len,		/* length to allocate */	xfs_buf_t	**rbpp,		/* in/out: summary block buffer */	xfs_fsblock_t	*rsb)		/* in/out: summary block number */{	xfs_rtblock_t	end;		/* end of the allocated extent */	int		error;		/* error value */	xfs_rtblock_t	postblock;	/* first block allocated > end */	xfs_rtblock_t	preblock;	/* first block allocated < start */	end = start + len - 1;	/*	 * Assume we're allocating out of the middle of a free extent.	 * We need to find the beginning and end of the extent so we can	 * properly update the summary.	 */	error = xfs_rtfind_back(mp, tp, start, 0, &preblock);	if (error) {		return error;	}	/*	 * Find the next allocated block (end of free extent).	 */	error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1,		&postblock);	if (error) {		return error;	}	/*	 * Decrement the summary information corresponding to the entire	 * (old) free extent.	 */	error = xfs_rtmodify_summary(mp, tp,		XFS_RTBLOCKLOG(postblock + 1 - preblock),		XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb);	if (error) {		return error;	}	/*	 * If there are blocks not being allocated at the front of the	 * old extent, add summary data for them to be free.	 */	if (preblock < start) {		error = xfs_rtmodify_summary(mp, tp,			XFS_RTBLOCKLOG(start - preblock),			XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb);		if (error) {			return error;		}	}	/*	 * If there are blocks not being allocated at the end of the	 * old extent, add summary data for them to be free.	 */	if (postblock > end) {		error = xfs_rtmodify_summary(mp, tp,			XFS_RTBLOCKLOG(postblock - end),			XFS_BITTOBLOCK(mp, end + 1), 1, rbpp, rsb);		if (error) {			return error;		}	}	/*	 * Modify the bitmap to mark this extent allocated.	 */	error = xfs_rtmodify_range(mp, tp, start, len, 0);	return error;}/* * Return whether there are any free extents in the size range given * by low and high, for the bitmap block bbno. */STATIC int				/* error */xfs_rtany_summary(	xfs_mount_t	*mp,		/* file system mount structure */	xfs_trans_t	*tp,		/* transaction pointer */	int		low,		/* low log2 extent size */	int		high,		/* high log2 extent size */	xfs_rtblock_t	bbno,		/* bitmap block number */	xfs_buf_t	**rbpp,		/* in/out: summary block buffer */	xfs_fsblock_t	*rsb,		/* in/out: summary block number */	int		*stat)		/* out: any good extents here? */{	int		error;		/* error value */	int		log;		/* loop counter, log2 of ext. size */	xfs_suminfo_t	sum;		/* summary data */	/*	 * Loop over logs of extent sizes.  Order is irrelevant.	 */	for (log = low; log <= high; log++) {		/*		 * Get one summary datum.		 */		error = xfs_rtget_summary(mp, tp, log, bbno, rbpp, rsb, &sum);		if (error) {			return error;		}		/*		 * If there are any, return success.		 */		if (sum) {			*stat = 1;			return 0;		}	}	/*	 * Found nothing, return failure.	 */	*stat = 0;	return 0;}/* * Get a buffer for the bitmap or summary file block specified. * The buffer is returned read and locked. */STATIC int				/* error */xfs_rtbuf_get(	xfs_mount_t	*mp,		/* file system mount structure */	xfs_trans_t	*tp,		/* transaction pointer */	xfs_rtblock_t	block,		/* block number in bitmap or summary */	int		issum,		/* is summary not bitmap */	xfs_buf_t	**bpp)		/* output: buffer for the block */{	xfs_buf_t	*bp;		/* block buffer, result */	xfs_daddr_t	d;		/* disk addr of block */	int		error;		/* error value */	xfs_fsblock_t	fsb;		/* fs block number for block */	xfs_inode_t	*ip;		/* bitmap or summary inode */	ip = issum ? mp->m_rsumip : mp->m_rbmip;	/*	 * Map from the file offset (block) and inode number to the	 * file system block.	 */	error = xfs_bmapi_single(tp, ip, XFS_DATA_FORK, &fsb, block);	if (error) {		return error;	}	ASSERT(fsb != NULLFSBLOCK);	/*	 * Convert to disk address for buffer cache.	 */	d = XFS_FSB_TO_DADDR(mp, fsb);	/*	 * Read the buffer.	 */	error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,				   mp->m_bsize, 0, &bp);	if (error) {		return error;	}	ASSERT(bp && !XFS_BUF_GETERROR(bp));	*bpp = bp;	return 0;}#ifdef DEBUG/* * Check that the given extent (block range) is allocated already. */STATIC int				/* error */xfs_rtcheck_alloc_range(	xfs_mount_t	*mp,		/* file system mount point */	xfs_trans_t	*tp,		/* transaction pointer */	xfs_rtblock_t	bno,		/* starting block number of extent */	xfs_extlen_t	len,		/* length of extent */	int		*stat)		/* out: 1 for allocated, 0 for not */{	xfs_rtblock_t	new;		/* dummy for xfs_rtcheck_range */	return xfs_rtcheck_range(mp, tp, bno, len, 0, &new, stat);}#endif/* * Check that the given range is either all allocated (val = 0) or * all free (val = 1). */STATIC int				/* error */xfs_rtcheck_range(	xfs_mount_t	*mp,		/* file system mount point */	xfs_trans_t	*tp,		/* transaction pointer */	xfs_rtblock_t	start,		/* starting block number of extent */	xfs_extlen_t	len,		/* length of extent */	int		val,		/* 1 for free, 0 for allocated */	xfs_rtblock_t	*new,		/* out: first block not matching */	int		*stat)		/* out: 1 for matches, 0 for not */{	xfs_rtword_t	*b;		/* current word in buffer */	int		bit;		/* bit number in the word */	xfs_rtblock_t	block;		/* bitmap block number */	xfs_buf_t	*bp;		/* buf for the block */	xfs_rtword_t	*bufp;		/* starting word in buffer */	int		error;		/* error value */	xfs_rtblock_t	i;		/* current bit number rel. to start */

⌨️ 快捷键说明

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