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

📄 xfs_rtalloc.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	xfs_rtblock_t	lastbit;	/* last useful bit in word */	xfs_rtword_t	mask;		/* mask of relevant bits for value */	xfs_rtword_t	wdiff;		/* difference from wanted value */	int		word;		/* word number in the buffer */	/*	 * Compute starting bitmap block number	 */	block = XFS_BITTOBLOCK(mp, start);	/*	 * Read the bitmap block.	 */	error = xfs_rtbuf_get(mp, tp, block, 0, &bp);	if (error) {		return error;	}	bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);	/*	 * Compute the starting word's address, and starting bit.	 */	word = XFS_BITTOWORD(mp, start);	b = &bufp[word];	bit = (int)(start & (XFS_NBWORD - 1));	/*	 * 0 (allocated) => all zero's; 1 (free) => all one's.	 */	val = -val;	/*	 * If not starting on a word boundary, deal with the first	 * (partial) word.	 */	if (bit) {		/*		 * Compute first bit not examined.		 */		lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);		/*		 * Mask of relevant bits.		 */		mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;		/*		 * Compute difference between actual and desired value.		 */		if ((wdiff = (*b ^ val) & mask)) {			/*			 * Different, compute first wrong bit and return.			 */			xfs_trans_brelse(tp, bp);			i = XFS_RTLOBIT(wdiff) - bit;			*new = start + i;			*stat = 0;			return 0;		}		i = lastbit - bit;		/*		 * Go on to next block if that's where the next word is		 * and we need the next word.		 */		if (++word == XFS_BLOCKWSIZE(mp) && i < len) {			/*			 * If done with this block, get the next one.			 */			xfs_trans_brelse(tp, bp);			error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);			if (error) {				return error;			}			b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);			word = 0;		} else {			/*			 * Go on to the next word in the buffer.			 */			b++;		}	} else {		/*		 * Starting on a word boundary, no partial word.		 */		i = 0;	}	/*	 * Loop over whole words in buffers.  When we use up one buffer	 * we move on to the next one.	 */	while (len - i >= XFS_NBWORD) {		/*		 * Compute difference between actual and desired value.		 */		if ((wdiff = *b ^ val)) {			/*			 * Different, compute first wrong bit and return.			 */			xfs_trans_brelse(tp, bp);			i += XFS_RTLOBIT(wdiff);			*new = start + i;			*stat = 0;			return 0;		}		i += XFS_NBWORD;		/*		 * Go on to next block if that's where the next word is		 * and we need the next word.		 */		if (++word == XFS_BLOCKWSIZE(mp) && i < len) {			/*			 * If done with this block, get the next one.			 */			xfs_trans_brelse(tp, bp);			error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);			if (error) {				return error;			}			b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);			word = 0;		} else {			/*			 * Go on to the next word in the buffer.			 */			b++;		}	}	/*	 * If not ending on a word boundary, deal with the last	 * (partial) word.	 */	if ((lastbit = len - i)) {		/*		 * Mask of relevant bits.		 */		mask = ((xfs_rtword_t)1 << lastbit) - 1;		/*		 * Compute difference between actual and desired value.		 */		if ((wdiff = (*b ^ val) & mask)) {			/*			 * Different, compute first wrong bit and return.			 */			xfs_trans_brelse(tp, bp);			i += XFS_RTLOBIT(wdiff);			*new = start + i;			*stat = 0;			return 0;		} else			i = len;	}	/*	 * Successful, return.	 */	xfs_trans_brelse(tp, bp);	*new = start + i;	*stat = 1;	return 0;}/* * Copy and transform the summary file, given the old and new * parameters in the mount structures. */STATIC int				/* error */xfs_rtcopy_summary(	xfs_mount_t	*omp,		/* old file system mount point */	xfs_mount_t	*nmp,		/* new file system mount point */	xfs_trans_t	*tp)		/* transaction pointer */{	xfs_rtblock_t	bbno;		/* bitmap block number */	xfs_buf_t	*bp;		/* summary buffer */	int		error;		/* error return value */	int		log;		/* summary level number (log length) */	xfs_suminfo_t	sum;		/* summary data */	xfs_fsblock_t	sumbno;		/* summary block number */	bp = NULL;	for (log = omp->m_rsumlevels - 1; log >= 0; log--) {		for (bbno = omp->m_sb.sb_rbmblocks - 1;		     (xfs_srtblock_t)bbno >= 0;		     bbno--) {			error = xfs_rtget_summary(omp, tp, log, bbno, &bp,				&sumbno, &sum);			if (error)				return error;			if (sum == 0)				continue;			error = xfs_rtmodify_summary(omp, tp, log, bbno, -sum,				&bp, &sumbno);			if (error)				return error;			error = xfs_rtmodify_summary(nmp, tp, log, bbno, sum,				&bp, &sumbno);			if (error)				return error;			ASSERT(sum > 0);		}	}	return 0;}/* * Searching backward from start to limit, find the first block whose * allocated/free state is different from start's. */STATIC int				/* error */xfs_rtfind_back(	xfs_mount_t	*mp,		/* file system mount point */	xfs_trans_t	*tp,		/* transaction pointer */	xfs_rtblock_t	start,		/* starting block to look at */	xfs_rtblock_t	limit,		/* last block to look at */	xfs_rtblock_t	*rtblock)	/* out: start block found */{	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	firstbit;	/* first useful bit in the word */	xfs_rtblock_t	i;		/* current bit number rel. to start */	xfs_rtblock_t	len;		/* length of inspected area */	xfs_rtword_t	mask;		/* mask of relevant bits for value */	xfs_rtword_t	want;		/* mask for "good" values */	xfs_rtword_t	wdiff;		/* difference from wanted value */	int		word;		/* word number in the buffer */	/*	 * Compute and read in starting bitmap block for starting block.	 */	block = XFS_BITTOBLOCK(mp, start);	error = xfs_rtbuf_get(mp, tp, block, 0, &bp);	if (error) {		return error;	}	bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);	/*	 * Get the first word's index & point to it.	 */	word = XFS_BITTOWORD(mp, start);	b = &bufp[word];	bit = (int)(start & (XFS_NBWORD - 1));	len = start - limit + 1;	/*	 * Compute match value, based on the bit at start: if 1 (free)	 * then all-ones, else all-zeroes.	 */	want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0;	/*	 * If the starting position is not word-aligned, deal with the	 * partial word.	 */	if (bit < XFS_NBWORD - 1) {		/*		 * Calculate first (leftmost) bit number to look at,		 * and mask for all the relevant bits in this word.		 */		firstbit = XFS_RTMAX((xfs_srtblock_t)(bit - len + 1), 0);		mask = (((xfs_rtword_t)1 << (bit - firstbit + 1)) - 1) <<			firstbit;		/*		 * Calculate the difference between the value there		 * and what we're looking for.		 */		if ((wdiff = (*b ^ want) & mask)) {			/*			 * Different.  Mark where we are and return.			 */			xfs_trans_brelse(tp, bp);			i = bit - XFS_RTHIBIT(wdiff);			*rtblock = start - i + 1;			return 0;		}		i = bit - firstbit + 1;		/*		 * Go on to previous block if that's where the previous word is		 * and we need the previous word.		 */		if (--word == -1 && i < len) {			/*			 * If done with this block, get the previous one.			 */			xfs_trans_brelse(tp, bp);			error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);			if (error) {				return error;			}			bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);			word = XFS_BLOCKWMASK(mp);			b = &bufp[word];		} else {			/*			 * Go on to the previous word in the buffer.			 */			b--;		}	} else {		/*		 * Starting on a word boundary, no partial word.		 */		i = 0;	}	/*	 * Loop over whole words in buffers.  When we use up one buffer	 * we move on to the previous one.	 */	while (len - i >= XFS_NBWORD) {		/*		 * Compute difference between actual and desired value.		 */		if ((wdiff = *b ^ want)) {			/*			 * Different, mark where we are and return.			 */			xfs_trans_brelse(tp, bp);			i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);			*rtblock = start - i + 1;			return 0;		}		i += XFS_NBWORD;		/*		 * Go on to previous block if that's where the previous word is		 * and we need the previous word.		 */		if (--word == -1 && i < len) {			/*			 * If done with this block, get the previous one.			 */			xfs_trans_brelse(tp, bp);			error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);			if (error) {				return error;			}			bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);			word = XFS_BLOCKWMASK(mp);			b = &bufp[word];		} else {			/*			 * Go on to the previous word in the buffer.			 */			b--;		}	}	/*	 * If not ending on a word boundary, deal with the last	 * (partial) word.	 */	if (len - i) {		/*		 * Calculate first (leftmost) bit number to look at,		 * and mask for all the relevant bits in this word.		 */		firstbit = XFS_NBWORD - (len - i);		mask = (((xfs_rtword_t)1 << (len - i)) - 1) << firstbit;		/*		 * Compute difference between actual and desired value.		 */		if ((wdiff = (*b ^ want) & mask)) {			/*			 * Different, mark where we are and return.			 */			xfs_trans_brelse(tp, bp);			i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);			*rtblock = start - i + 1;			return 0;		} else			i = len;	}	/*	 * No match, return that we scanned the whole area.	 */	xfs_trans_brelse(tp, bp);	*rtblock = start - i + 1;	return 0;}/* * Searching forward from start to limit, find the first block whose * allocated/free state is different from start's. */STATIC int				/* error */xfs_rtfind_forw(	xfs_mount_t	*mp,		/* file system mount point */	xfs_trans_t	*tp,		/* transaction pointer */	xfs_rtblock_t	start,		/* starting block to look at */	xfs_rtblock_t	limit,		/* last block to look at */	xfs_rtblock_t	*rtblock)	/* out: start block found */{	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 */	xfs_rtblock_t	lastbit;	/* last useful bit in the word */	xfs_rtblock_t	len;		/* length of inspected area */	xfs_rtword_t	mask;		/* mask of relevant bits for value */	xfs_rtword_t	want;		/* mask for "good" values */	xfs_rtword_t	wdiff;		/* difference from wanted value */	int		word;		/* word number in the buffer */	/*	 * Compute and read in starting bitmap block for starting block.	 */	block = XFS_BITTOBLOCK(mp, start);	error = xfs_rtbuf_get(mp, tp, block, 0, &bp);	if (error) {		return error;	}	bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);	/*	 * Get the first word's index & point to it.	 */	word = XFS_BITTOWORD(mp, start);	b = &bufp[word];	bit = (int)(start & (XFS_NBWORD - 1));	len = limit - start + 1;	/*	 * Compute match value, based on the bit at start: if 1 (free)	 * then all-ones, else all-zeroes.	 */	want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0;	/*	 * If the starting position is not word-aligned, deal with the	 * partial word.	 */	if (bit) {		/*		 * Calculate last (rightmost) bit number to look at,		 * and mask for all the relevant bits in this word.		 */		lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);		mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;		/*		 * Calculate the difference between the value there		 * and what we're looking for.		 */		if ((wdiff = (*b ^ want) & mask)) {			/*			 * Different.  Mark where we are and return.			 */			xfs_trans_brelse(tp, bp);			i = XFS_RTLOBIT(wdiff) - bit;			*rtblock = start + i - 1;			return 0;		}		i = lastbit - bit;		/*		 * Go on to next block if that's where the next word is		 * and we need the next word.		 */		if (++word == XFS_BLOCKWSIZE(mp) && i < len) {			/*			 * If done with this block, get the previous one.			 */			xfs_trans_brelse(tp, bp);			error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);			if (error) {				return error;			}			b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);			word = 0;		} else {			/*			 * Go on to the previous word in the buffer.			 */			b++;		}	} else {		/*		 * Starting on a word boundary, no partial word.

⌨️ 快捷键说明

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