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

📄 xfs_rtalloc.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		 */		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 ^ want)) {			/*			 * Different, mark where we are and return.			 */			xfs_trans_brelse(tp, bp);			i += XFS_RTLOBIT(wdiff);			*rtblock = start + i - 1;			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)) {		/*		 * Calculate mask for all the relevant bits in this word.		 */		mask = ((xfs_rtword_t)1 << lastbit) - 1;		/*		 * 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_RTLOBIT(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;}/* * Mark an extent specified by start and len freed. * Updates all the summary information as well as the bitmap. */STATIC int				/* error */xfs_rtfree_range(	xfs_mount_t	*mp,		/* file system mount point */	xfs_trans_t	*tp,		/* transaction pointer */	xfs_rtblock_t	start,		/* starting block to free */	xfs_extlen_t	len,		/* length to free */	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 freed extent */	int		error;		/* error value */	xfs_rtblock_t	postblock;	/* first block freed > end */	xfs_rtblock_t	preblock;	/* first block freed < start */	end = start + len - 1;	/*	 * Modify the bitmap to mark this extent freed.	 */	error = xfs_rtmodify_range(mp, tp, start, len, 1);	if (error) {		return error;	}	/*	 * Assume we're freeing out of the middle of an allocated 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 allocated extent).	 */	error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1,		&postblock);	/*	 * If there are blocks not being freed at the front of the	 * old extent, add summary data for them to be allocated.	 */	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 freed at the end of the	 * old extent, add summary data for them to be allocated.	 */	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;		}	}	/*	 * Increment the summary information corresponding to the entire	 * (new) free extent.	 */	error = xfs_rtmodify_summary(mp, tp,		XFS_RTBLOCKLOG(postblock + 1 - preblock),		XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb);	return error;}/* * Read and return the summary information for a given extent size, * bitmap block combination. * Keeps track of a current summary block, so we don't keep reading * it from the buffer cache. */STATIC int				/* error */xfs_rtget_summary(	xfs_mount_t	*mp,		/* file system mount structure */	xfs_trans_t	*tp,		/* transaction pointer */	int		log,		/* log2 of 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 */	xfs_suminfo_t	*sum)		/* out: summary info for this block */{	xfs_buf_t	*bp;		/* buffer for summary block */	int		error;		/* error value */	xfs_fsblock_t	sb;		/* summary fsblock */	int		so;		/* index into the summary file */	xfs_suminfo_t	*sp;		/* pointer to returned data */	/*	 * Compute entry number in the summary file.	 */	so = XFS_SUMOFFS(mp, log, bbno);	/*	 * Compute the block number in the summary file.	 */	sb = XFS_SUMOFFSTOBLOCK(mp, so);	/*	 * If we have an old buffer, and the block number matches, use that.	 */	if (rbpp && *rbpp && *rsb == sb)		bp = *rbpp;	/*	 * Otherwise we have to get the buffer.	 */	else {		/*		 * If there was an old one, get rid of it first.		 */		if (rbpp && *rbpp)			xfs_trans_brelse(tp, *rbpp);		error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);		if (error) {			return error;		}		/*		 * Remember this buffer and block for the next call.		 */		if (rbpp) {			*rbpp = bp;			*rsb = sb;		}	}	/*	 * Point to the summary information & copy it out.	 */	sp = XFS_SUMPTR(mp, bp, so);	*sum = *sp;	/*	 * Drop the buffer if we're not asked to remember it.	 */	if (!rbpp)		xfs_trans_brelse(tp, bp);	return 0;}/* * Set the given range of bitmap bits to the given value. * Do whatever I/O and logging is required. */STATIC int				/* error */xfs_rtmodify_range(	xfs_mount_t	*mp,		/* file system mount point */	xfs_trans_t	*tp,		/* transaction pointer */	xfs_rtblock_t	start,		/* starting block to modify */	xfs_extlen_t	len,		/* length of extent to modify */	int		val)		/* 1 for free, 0 for allocated */{	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_rtword_t	*first;		/* first used word in the buffer */	int		i;		/* current bit number rel. to start */	int		lastbit;	/* last useful bit in word */	xfs_rtword_t	mask;		/* mask o frelevant bits for value */	int		word;		/* word number in the buffer */	/*	 * Compute starting bitmap block number.	 */	block = XFS_BITTOBLOCK(mp, start);	/*	 * Read the bitmap block, and point to its data.	 */	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);	first = b = &bufp[word];	bit = (int)(start & (XFS_NBWORD - 1));	/*	 * 0 (allocated) => all zeroes; 1 (free) => all ones.	 */	val = -val;	/*	 * If not starting on a word boundary, deal with the first	 * (partial) word.	 */	if (bit) {		/*		 * Compute first bit not changed and mask of relevant bits.		 */		lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);		mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;		/*		 * Set/clear the active bits.		 */		if (val)			*b |= mask;		else			*b &= ~mask;		i = lastbit - bit;		/*		 * Go on to the next block if that's where the next word is		 * and we need the next word.		 */		if (++word == XFS_BLOCKWSIZE(mp) && i < len) {			/*			 * Log the changed part of this block.			 * Get the next one.			 */			xfs_trans_log_buf(tp, bp,				(uint)((char *)first - (char *)bufp),				(uint)((char *)b - (char *)bufp));			error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);			if (error) {				return error;			}			first = 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) {		/*		 * Set the word value correctly.		 */		*b = val;		i += XFS_NBWORD;		/*		 * Go on to the next block if that's where the next word is		 * and we need the next word.		 */		if (++word == XFS_BLOCKWSIZE(mp) && i < len) {			/*			 * Log the changed part of this block.			 * Get the next one.			 */			xfs_trans_log_buf(tp, bp,				(uint)((char *)first - (char *)bufp),				(uint)((char *)b - (char *)bufp));			error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);			if (error) {				return error;			}			first = 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)) {		/*		 * Compute a mask of relevant bits.		 */		bit = 0;		mask = ((xfs_rtword_t)1 << lastbit) - 1;		/*		 * Set/clear the active bits.		 */		if (val)			*b |= mask;		else			*b &= ~mask;		b++;	}	/*	 * Log any remaining changed bytes.	 */	if (b > first)		xfs_trans_log_buf(tp, bp, (uint)((char *)first - (char *)bufp),			(uint)((char *)b - (char *)bufp - 1));	return 0;}/* * Read and modify the summary information for a given extent size, * bitmap block combination. * Keeps track of a current summary block, so we don't keep reading * it from the buffer cache. */STATIC int				/* error */xfs_rtmodify_summary(	xfs_mount_t	*mp,		/* file system mount point */	xfs_trans_t	*tp,		/* transaction pointer */	int		log,		/* log2 of extent size */	xfs_rtblock_t	bbno,		/* bitmap block number */	int		delta,		/* change to make to summary info */	xfs_buf_t	**rbpp,		/* in/out: summary block buffer */	xfs_fsblock_t	*rsb)		/* in/out: summary block number */{	xfs_buf_t	*bp;		/* buffer for the summary block */	int		error;		/* error value */	xfs_fsblock_t	sb;		/* summary fsblock */	int		so;		/* index into the summary file */	xfs_suminfo_t	*sp;		/* pointer to returned data */	/*	 * Compute entry number in the summary file.	 */	so = XFS_SUMOFFS(mp, log, bbno);	/*	 * Compute the block number in the summary file.	 */	sb = XFS_SUMOFFSTOBLOCK(mp, so);	/*	 * If we have an old buffer, and the block number matches, use that.	 */	if (rbpp && *rbpp && *rsb == sb)		bp = *rbpp;	/*	 * Otherwise we have to get the buffer.	 */	else {		/*		 * If there was an old one, get rid of it first.		 */		if (rbpp && *rbpp)			xfs_trans_brelse(tp, *rbpp);		error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);		if (error) {			return error;		}		/*		 * Remember this buffer and block for the next call.		 */		if (rbpp) {			*rbpp = bp;			*rsb = sb;		}	}	/*	 * Point to the summary information, modify and log it.	 */	sp = XFS_SUMPTR(mp, bp, so);	*sp += delta;	xfs_trans_log_buf(tp, bp, (uint)((char *)sp - (char *)XFS_BUF_PTR(bp)),		(uint)((char *)sp - (char *)XFS_BUF_PTR(bp) + sizeof(*sp) - 1));	return 0;}/* * Visible (exported) functions. *//* * Grow the realtime area of the filesystem. */intxfs_growfs_rt(	xfs_mount_t	*mp,		/* mount point for filesystem */	xfs_growfs_rt_t	*in)		/* growfs rt input struct */{	xfs_rtblock_t	bmbno;		/* bitmap block number */	xfs_buf_t	*bp;		/* temporary buffer */	int		cancelflags;	/* flags for xfs_trans_cancel */	int		error;		/* error return value */	xfs_inode_t	*ip;		/* bitmap inode, used as lock */	xfs_mount_t	*nmp;		/* new (fake) mount structure */	xfs_drfsbno_t	nrblocks;	/* new number of realtime blocks */	xfs_extlen_t	nrbmblocks;	/* new number of rt bitmap blocks */	xfs_drtbno_t	nrextents;	/* new number of realtime extents */	uint8_t		nrextslog;	/* new log2 of sb_rextents */	xfs_extlen_t	nrsumblocks;	/* new number of summary blocks */	uint		nrsumlevels;	/* new rt summary levels */	uint		nrsumsize;	/* new size of rt summary, bytes */	xfs_sb_t	*nsbp;		/* new superblock */	xfs_extlen_t	rbmblocks;	/* current number of rt bitmap blocks */	xfs_extlen_t	rsumblocks;	/* current number of rt summary blks */

⌨️ 快捷键说明

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