diff options
Diffstat (limited to 'fs/xfs/xfs_fsops.c')
| -rw-r--r-- | fs/xfs/xfs_fsops.c | 141 | 
1 files changed, 94 insertions, 47 deletions
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 4beaede4327..94eaeedc549 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -97,7 +97,9 @@ xfs_fs_geometry(  			(xfs_sb_version_haslazysbcount(&mp->m_sb) ?  				XFS_FSOP_GEOM_FLAGS_LAZYSB : 0) |  			(xfs_sb_version_hasattr2(&mp->m_sb) ? -				XFS_FSOP_GEOM_FLAGS_ATTR2 : 0); +				XFS_FSOP_GEOM_FLAGS_ATTR2 : 0) | +			(xfs_sb_version_hasprojid32bit(&mp->m_sb) ? +				XFS_FSOP_GEOM_FLAGS_PROJID32 : 0);  		geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ?  				mp->m_sb.sb_logsectsize : BBSIZE;  		geo->rtsectsize = mp->m_sb.sb_blocksize; @@ -112,18 +114,40 @@ xfs_fs_geometry(  	return 0;  } +static struct xfs_buf * +xfs_growfs_get_hdr_buf( +	struct xfs_mount	*mp, +	xfs_daddr_t		blkno, +	size_t			numblks, +	int			flags, +	const struct xfs_buf_ops *ops) +{ +	struct xfs_buf		*bp; + +	bp = xfs_buf_get_uncached(mp->m_ddev_targp, numblks, flags); +	if (!bp) +		return NULL; + +	xfs_buf_zero(bp, 0, BBTOB(bp->b_length)); +	bp->b_bn = blkno; +	bp->b_maps[0].bm_bn = blkno; +	bp->b_ops = ops; + +	return bp; +} +  static int  xfs_growfs_data_private(  	xfs_mount_t		*mp,		/* mount point for filesystem */  	xfs_growfs_data_t	*in)		/* growfs data input struct */  {  	xfs_agf_t		*agf; +	struct xfs_agfl		*agfl;  	xfs_agi_t		*agi;  	xfs_agnumber_t		agno;  	xfs_extlen_t		agsize;  	xfs_extlen_t		tmpsize;  	xfs_alloc_rec_t		*arec; -	struct xfs_btree_block	*block;  	xfs_buf_t		*bp;  	int			bucket;  	int			dpct; @@ -146,9 +170,14 @@ xfs_growfs_data_private(  	dpct = pct - mp->m_sb.sb_imax_pct;  	bp = xfs_buf_read_uncached(mp->m_ddev_targp,  				XFS_FSB_TO_BB(mp, nb) - XFS_FSS_TO_BB(mp, 1), -				XFS_FSS_TO_BB(mp, 1), 0); +				XFS_FSS_TO_BB(mp, 1), 0, NULL);  	if (!bp)  		return EIO; +	if (bp->b_error) { +		int	error = bp->b_error; +		xfs_buf_relse(bp); +		return error; +	}  	xfs_buf_relse(bp);  	new = nb;	/* use new as a temporary here */ @@ -186,17 +215,18 @@ xfs_growfs_data_private(  	nfree = 0;  	for (agno = nagcount - 1; agno >= oagcount; agno--, new -= agsize) {  		/* -		 * AG freelist header block +		 * AG freespace header block  		 */ -		bp = xfs_buf_get(mp->m_ddev_targp, -				 XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), -				 XFS_FSS_TO_BB(mp, 1), 0); +		bp = xfs_growfs_get_hdr_buf(mp, +				XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), +				XFS_FSS_TO_BB(mp, 1), 0, +				&xfs_agf_buf_ops);  		if (!bp) {  			error = ENOMEM;  			goto error0;  		} +  		agf = XFS_BUF_TO_AGF(bp); -		memset(agf, 0, mp->m_sb.sb_sectsize);  		agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);  		agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);  		agf->agf_seqno = cpu_to_be32(agno); @@ -223,17 +253,39 @@ xfs_growfs_data_private(  			goto error0;  		/* +		 * AG freelist header block +		 */ +		bp = xfs_growfs_get_hdr_buf(mp, +				XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)), +				XFS_FSS_TO_BB(mp, 1), 0, +				&xfs_agfl_buf_ops); +		if (!bp) { +			error = ENOMEM; +			goto error0; +		} + +		agfl = XFS_BUF_TO_AGFL(bp); +		for (bucket = 0; bucket < XFS_AGFL_SIZE(mp); bucket++) +			agfl->agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK); + +		error = xfs_bwrite(bp); +		xfs_buf_relse(bp); +		if (error) +			goto error0; + +		/*  		 * AG inode header block  		 */ -		bp = xfs_buf_get(mp->m_ddev_targp, -				 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), -				 XFS_FSS_TO_BB(mp, 1), 0); +		bp = xfs_growfs_get_hdr_buf(mp, +				XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), +				XFS_FSS_TO_BB(mp, 1), 0, +				&xfs_agi_buf_ops);  		if (!bp) {  			error = ENOMEM;  			goto error0;  		} +  		agi = XFS_BUF_TO_AGI(bp); -		memset(agi, 0, mp->m_sb.sb_sectsize);  		agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);  		agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);  		agi->agi_seqno = cpu_to_be32(agno); @@ -254,24 +306,22 @@ xfs_growfs_data_private(  		/*  		 * BNO btree root block  		 */ -		bp = xfs_buf_get(mp->m_ddev_targp, -				 XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)), -				 BTOBB(mp->m_sb.sb_blocksize), 0); +		bp = xfs_growfs_get_hdr_buf(mp, +				XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)), +				BTOBB(mp->m_sb.sb_blocksize), 0, +				&xfs_allocbt_buf_ops); +  		if (!bp) {  			error = ENOMEM;  			goto error0;  		} -		block = XFS_BUF_TO_BLOCK(bp); -		memset(block, 0, mp->m_sb.sb_blocksize); -		block->bb_magic = cpu_to_be32(XFS_ABTB_MAGIC); -		block->bb_level = 0; -		block->bb_numrecs = cpu_to_be16(1); -		block->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); -		block->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); -		arec = XFS_ALLOC_REC_ADDR(mp, block, 1); + +		xfs_btree_init_block(mp, bp, XFS_ABTB_MAGIC, 0, 1, 0); +		arec = XFS_ALLOC_REC_ADDR(mp, XFS_BUF_TO_BLOCK(bp), 1);  		arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));  		arec->ar_blockcount = cpu_to_be32(  			agsize - be32_to_cpu(arec->ar_startblock)); +  		error = xfs_bwrite(bp);  		xfs_buf_relse(bp);  		if (error) @@ -280,25 +330,22 @@ xfs_growfs_data_private(  		/*  		 * CNT btree root block  		 */ -		bp = xfs_buf_get(mp->m_ddev_targp, -				 XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)), -				 BTOBB(mp->m_sb.sb_blocksize), 0); +		bp = xfs_growfs_get_hdr_buf(mp, +				XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)), +				BTOBB(mp->m_sb.sb_blocksize), 0, +				&xfs_allocbt_buf_ops);  		if (!bp) {  			error = ENOMEM;  			goto error0;  		} -		block = XFS_BUF_TO_BLOCK(bp); -		memset(block, 0, mp->m_sb.sb_blocksize); -		block->bb_magic = cpu_to_be32(XFS_ABTC_MAGIC); -		block->bb_level = 0; -		block->bb_numrecs = cpu_to_be16(1); -		block->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); -		block->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); -		arec = XFS_ALLOC_REC_ADDR(mp, block, 1); + +		xfs_btree_init_block(mp, bp, XFS_ABTC_MAGIC, 0, 1, 0); +		arec = XFS_ALLOC_REC_ADDR(mp, XFS_BUF_TO_BLOCK(bp), 1);  		arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));  		arec->ar_blockcount = cpu_to_be32(  			agsize - be32_to_cpu(arec->ar_startblock));  		nfree += be32_to_cpu(arec->ar_blockcount); +  		error = xfs_bwrite(bp);  		xfs_buf_relse(bp);  		if (error) @@ -307,20 +354,17 @@ xfs_growfs_data_private(  		/*  		 * INO btree root block  		 */ -		bp = xfs_buf_get(mp->m_ddev_targp, -				 XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)), -				 BTOBB(mp->m_sb.sb_blocksize), 0); +		bp = xfs_growfs_get_hdr_buf(mp, +				XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)), +				BTOBB(mp->m_sb.sb_blocksize), 0, +				&xfs_inobt_buf_ops);  		if (!bp) {  			error = ENOMEM;  			goto error0;  		} -		block = XFS_BUF_TO_BLOCK(bp); -		memset(block, 0, mp->m_sb.sb_blocksize); -		block->bb_magic = cpu_to_be32(XFS_IBT_MAGIC); -		block->bb_level = 0; -		block->bb_numrecs = 0; -		block->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); -		block->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); + +		xfs_btree_init_block(mp, bp, XFS_IBT_MAGIC, 0, 0, 0); +  		error = xfs_bwrite(bp);  		xfs_buf_relse(bp);  		if (error) @@ -408,14 +452,16 @@ xfs_growfs_data_private(  		if (agno < oagcount) {  			error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,  				  XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)), -				  XFS_FSS_TO_BB(mp, 1), 0, &bp); +				  XFS_FSS_TO_BB(mp, 1), 0, &bp, +				  &xfs_sb_buf_ops);  		} else {  			bp = xfs_trans_get_buf(NULL, mp->m_ddev_targp,  				  XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),  				  XFS_FSS_TO_BB(mp, 1), 0); -			if (bp) +			if (bp) { +				bp->b_ops = &xfs_sb_buf_ops;  				xfs_buf_zero(bp, 0, BBTOB(bp->b_length)); -			else +			} else  				error = ENOMEM;  		} @@ -426,6 +472,7 @@ xfs_growfs_data_private(  			break;  		}  		xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, XFS_SB_ALL_BITS); +  		/*  		 * If we get an error writing out the alternate superblocks,  		 * just issue a warning and continue.  The real work is  |