• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3   * All Rights Reserved.
4   *
5   * This program is free software; you can redistribute it and/or
6   * modify it under the terms of the GNU General Public License as
7   * published by the Free Software Foundation.
8   *
9   * This program is distributed in the hope that it would be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program; if not, write the Free Software Foundation,
16   * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17   */
18  #include "xfs.h"
19  #include "xfs_fs.h"
20  #include "xfs_shared.h"
21  #include "xfs_format.h"
22  #include "xfs_log_format.h"
23  #include "xfs_trans_resv.h"
24  #include "xfs_sb.h"
25  #include "xfs_mount.h"
26  #include "xfs_da_format.h"
27  #include "xfs_da_btree.h"
28  #include "xfs_inode.h"
29  #include "xfs_trans.h"
30  #include "xfs_inode_item.h"
31  #include "xfs_error.h"
32  #include "xfs_btree.h"
33  #include "xfs_alloc_btree.h"
34  #include "xfs_alloc.h"
35  #include "xfs_ialloc.h"
36  #include "xfs_fsops.h"
37  #include "xfs_itable.h"
38  #include "xfs_trans_space.h"
39  #include "xfs_rtalloc.h"
40  #include "xfs_trace.h"
41  #include "xfs_log.h"
42  #include "xfs_filestream.h"
43  
44  /*
45   * File system operations
46   */
47  
48  int
xfs_fs_geometry(xfs_mount_t * mp,xfs_fsop_geom_t * geo,int new_version)49  xfs_fs_geometry(
50  	xfs_mount_t		*mp,
51  	xfs_fsop_geom_t		*geo,
52  	int			new_version)
53  {
54  
55  	memset(geo, 0, sizeof(*geo));
56  
57  	geo->blocksize = mp->m_sb.sb_blocksize;
58  	geo->rtextsize = mp->m_sb.sb_rextsize;
59  	geo->agblocks = mp->m_sb.sb_agblocks;
60  	geo->agcount = mp->m_sb.sb_agcount;
61  	geo->logblocks = mp->m_sb.sb_logblocks;
62  	geo->sectsize = mp->m_sb.sb_sectsize;
63  	geo->inodesize = mp->m_sb.sb_inodesize;
64  	geo->imaxpct = mp->m_sb.sb_imax_pct;
65  	geo->datablocks = mp->m_sb.sb_dblocks;
66  	geo->rtblocks = mp->m_sb.sb_rblocks;
67  	geo->rtextents = mp->m_sb.sb_rextents;
68  	geo->logstart = mp->m_sb.sb_logstart;
69  	ASSERT(sizeof(geo->uuid)==sizeof(mp->m_sb.sb_uuid));
70  	memcpy(geo->uuid, &mp->m_sb.sb_uuid, sizeof(mp->m_sb.sb_uuid));
71  	if (new_version >= 2) {
72  		geo->sunit = mp->m_sb.sb_unit;
73  		geo->swidth = mp->m_sb.sb_width;
74  	}
75  	if (new_version >= 3) {
76  		geo->version = XFS_FSOP_GEOM_VERSION;
77  		geo->flags = XFS_FSOP_GEOM_FLAGS_NLINK |
78  			     XFS_FSOP_GEOM_FLAGS_DIRV2 |
79  			(xfs_sb_version_hasattr(&mp->m_sb) ?
80  				XFS_FSOP_GEOM_FLAGS_ATTR : 0) |
81  			(xfs_sb_version_hasquota(&mp->m_sb) ?
82  				XFS_FSOP_GEOM_FLAGS_QUOTA : 0) |
83  			(xfs_sb_version_hasalign(&mp->m_sb) ?
84  				XFS_FSOP_GEOM_FLAGS_IALIGN : 0) |
85  			(xfs_sb_version_hasdalign(&mp->m_sb) ?
86  				XFS_FSOP_GEOM_FLAGS_DALIGN : 0) |
87  			(xfs_sb_version_hasextflgbit(&mp->m_sb) ?
88  				XFS_FSOP_GEOM_FLAGS_EXTFLG : 0) |
89  			(xfs_sb_version_hassector(&mp->m_sb) ?
90  				XFS_FSOP_GEOM_FLAGS_SECTOR : 0) |
91  			(xfs_sb_version_hasasciici(&mp->m_sb) ?
92  				XFS_FSOP_GEOM_FLAGS_DIRV2CI : 0) |
93  			(xfs_sb_version_haslazysbcount(&mp->m_sb) ?
94  				XFS_FSOP_GEOM_FLAGS_LAZYSB : 0) |
95  			(xfs_sb_version_hasattr2(&mp->m_sb) ?
96  				XFS_FSOP_GEOM_FLAGS_ATTR2 : 0) |
97  			(xfs_sb_version_hasprojid32bit(&mp->m_sb) ?
98  				XFS_FSOP_GEOM_FLAGS_PROJID32 : 0) |
99  			(xfs_sb_version_hascrc(&mp->m_sb) ?
100  				XFS_FSOP_GEOM_FLAGS_V5SB : 0) |
101  			(xfs_sb_version_hasftype(&mp->m_sb) ?
102  				XFS_FSOP_GEOM_FLAGS_FTYPE : 0) |
103  			(xfs_sb_version_hasfinobt(&mp->m_sb) ?
104  				XFS_FSOP_GEOM_FLAGS_FINOBT : 0) |
105  			(xfs_sb_version_hassparseinodes(&mp->m_sb) ?
106  				XFS_FSOP_GEOM_FLAGS_SPINODES : 0);
107  		geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ?
108  				mp->m_sb.sb_logsectsize : BBSIZE;
109  		geo->rtsectsize = mp->m_sb.sb_blocksize;
110  		geo->dirblocksize = mp->m_dir_geo->blksize;
111  	}
112  	if (new_version >= 4) {
113  		geo->flags |=
114  			(xfs_sb_version_haslogv2(&mp->m_sb) ?
115  				XFS_FSOP_GEOM_FLAGS_LOGV2 : 0);
116  		geo->logsunit = mp->m_sb.sb_logsunit;
117  	}
118  	return 0;
119  }
120  
121  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)122  xfs_growfs_get_hdr_buf(
123  	struct xfs_mount	*mp,
124  	xfs_daddr_t		blkno,
125  	size_t			numblks,
126  	int			flags,
127  	const struct xfs_buf_ops *ops)
128  {
129  	struct xfs_buf		*bp;
130  
131  	bp = xfs_buf_get_uncached(mp->m_ddev_targp, numblks, flags);
132  	if (!bp)
133  		return NULL;
134  
135  	xfs_buf_zero(bp, 0, BBTOB(bp->b_length));
136  	bp->b_bn = blkno;
137  	bp->b_maps[0].bm_bn = blkno;
138  	bp->b_ops = ops;
139  
140  	return bp;
141  }
142  
143  static int
xfs_growfs_data_private(xfs_mount_t * mp,xfs_growfs_data_t * in)144  xfs_growfs_data_private(
145  	xfs_mount_t		*mp,		/* mount point for filesystem */
146  	xfs_growfs_data_t	*in)		/* growfs data input struct */
147  {
148  	xfs_agf_t		*agf;
149  	struct xfs_agfl		*agfl;
150  	xfs_agi_t		*agi;
151  	xfs_agnumber_t		agno;
152  	xfs_extlen_t		agsize;
153  	xfs_extlen_t		tmpsize;
154  	xfs_alloc_rec_t		*arec;
155  	xfs_buf_t		*bp;
156  	int			bucket;
157  	int			dpct;
158  	int			error, saved_error = 0;
159  	xfs_agnumber_t		nagcount;
160  	xfs_agnumber_t		nagimax = 0;
161  	xfs_rfsblock_t		nb, nb_mod;
162  	xfs_rfsblock_t		new;
163  	xfs_rfsblock_t		nfree;
164  	xfs_agnumber_t		oagcount;
165  	int			pct;
166  	xfs_trans_t		*tp;
167  
168  	nb = in->newblocks;
169  	pct = in->imaxpct;
170  	if (nb < mp->m_sb.sb_dblocks || pct < 0 || pct > 100)
171  		return -EINVAL;
172  	if ((error = xfs_sb_validate_fsb_count(&mp->m_sb, nb)))
173  		return error;
174  	dpct = pct - mp->m_sb.sb_imax_pct;
175  	error = xfs_buf_read_uncached(mp->m_ddev_targp,
176  				XFS_FSB_TO_BB(mp, nb) - XFS_FSS_TO_BB(mp, 1),
177  				XFS_FSS_TO_BB(mp, 1), 0, &bp, NULL);
178  	if (error)
179  		return error;
180  	xfs_buf_relse(bp);
181  
182  	new = nb;	/* use new as a temporary here */
183  	nb_mod = do_div(new, mp->m_sb.sb_agblocks);
184  	nagcount = new + (nb_mod != 0);
185  	if (nb_mod && nb_mod < XFS_MIN_AG_BLOCKS) {
186  		nagcount--;
187  		nb = (xfs_rfsblock_t)nagcount * mp->m_sb.sb_agblocks;
188  		if (nb < mp->m_sb.sb_dblocks)
189  			return -EINVAL;
190  	}
191  	new = nb - mp->m_sb.sb_dblocks;
192  	oagcount = mp->m_sb.sb_agcount;
193  
194  	/* allocate the new per-ag structures */
195  	if (nagcount > oagcount) {
196  		error = xfs_initialize_perag(mp, nagcount, &nagimax);
197  		if (error)
198  			return error;
199  	}
200  
201  	tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFS);
202  	tp->t_flags |= XFS_TRANS_RESERVE;
203  	error = xfs_trans_reserve(tp, &M_RES(mp)->tr_growdata,
204  				  XFS_GROWFS_SPACE_RES(mp), 0);
205  	if (error) {
206  		xfs_trans_cancel(tp);
207  		return error;
208  	}
209  
210  	/*
211  	 * Write new AG headers to disk. Non-transactional, but written
212  	 * synchronously so they are completed prior to the growfs transaction
213  	 * being logged.
214  	 */
215  	nfree = 0;
216  	for (agno = nagcount - 1; agno >= oagcount; agno--, new -= agsize) {
217  		__be32	*agfl_bno;
218  
219  		/*
220  		 * AG freespace header block
221  		 */
222  		bp = xfs_growfs_get_hdr_buf(mp,
223  				XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
224  				XFS_FSS_TO_BB(mp, 1), 0,
225  				&xfs_agf_buf_ops);
226  		if (!bp) {
227  			error = -ENOMEM;
228  			goto error0;
229  		}
230  
231  		agf = XFS_BUF_TO_AGF(bp);
232  		agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
233  		agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
234  		agf->agf_seqno = cpu_to_be32(agno);
235  		if (agno == nagcount - 1)
236  			agsize =
237  				nb -
238  				(agno * (xfs_rfsblock_t)mp->m_sb.sb_agblocks);
239  		else
240  			agsize = mp->m_sb.sb_agblocks;
241  		agf->agf_length = cpu_to_be32(agsize);
242  		agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp));
243  		agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
244  		agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
245  		agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1);
246  		agf->agf_flfirst = cpu_to_be32(1);
247  		agf->agf_fllast = 0;
248  		agf->agf_flcount = 0;
249  		tmpsize = agsize - XFS_PREALLOC_BLOCKS(mp);
250  		agf->agf_freeblks = cpu_to_be32(tmpsize);
251  		agf->agf_longest = cpu_to_be32(tmpsize);
252  		if (xfs_sb_version_hascrc(&mp->m_sb))
253  			uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid);
254  
255  		error = xfs_bwrite(bp);
256  		xfs_buf_relse(bp);
257  		if (error)
258  			goto error0;
259  
260  		/*
261  		 * AG freelist header block
262  		 */
263  		bp = xfs_growfs_get_hdr_buf(mp,
264  				XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
265  				XFS_FSS_TO_BB(mp, 1), 0,
266  				&xfs_agfl_buf_ops);
267  		if (!bp) {
268  			error = -ENOMEM;
269  			goto error0;
270  		}
271  
272  		agfl = XFS_BUF_TO_AGFL(bp);
273  		if (xfs_sb_version_hascrc(&mp->m_sb)) {
274  			agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC);
275  			agfl->agfl_seqno = cpu_to_be32(agno);
276  			uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid);
277  		}
278  
279  		agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, bp);
280  		for (bucket = 0; bucket < XFS_AGFL_SIZE(mp); bucket++)
281  			agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK);
282  
283  		error = xfs_bwrite(bp);
284  		xfs_buf_relse(bp);
285  		if (error)
286  			goto error0;
287  
288  		/*
289  		 * AG inode header block
290  		 */
291  		bp = xfs_growfs_get_hdr_buf(mp,
292  				XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
293  				XFS_FSS_TO_BB(mp, 1), 0,
294  				&xfs_agi_buf_ops);
295  		if (!bp) {
296  			error = -ENOMEM;
297  			goto error0;
298  		}
299  
300  		agi = XFS_BUF_TO_AGI(bp);
301  		agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
302  		agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
303  		agi->agi_seqno = cpu_to_be32(agno);
304  		agi->agi_length = cpu_to_be32(agsize);
305  		agi->agi_count = 0;
306  		agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp));
307  		agi->agi_level = cpu_to_be32(1);
308  		agi->agi_freecount = 0;
309  		agi->agi_newino = cpu_to_be32(NULLAGINO);
310  		agi->agi_dirino = cpu_to_be32(NULLAGINO);
311  		if (xfs_sb_version_hascrc(&mp->m_sb))
312  			uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid);
313  		if (xfs_sb_version_hasfinobt(&mp->m_sb)) {
314  			agi->agi_free_root = cpu_to_be32(XFS_FIBT_BLOCK(mp));
315  			agi->agi_free_level = cpu_to_be32(1);
316  		}
317  		for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++)
318  			agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
319  
320  		error = xfs_bwrite(bp);
321  		xfs_buf_relse(bp);
322  		if (error)
323  			goto error0;
324  
325  		/*
326  		 * BNO btree root block
327  		 */
328  		bp = xfs_growfs_get_hdr_buf(mp,
329  				XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)),
330  				BTOBB(mp->m_sb.sb_blocksize), 0,
331  				&xfs_allocbt_buf_ops);
332  
333  		if (!bp) {
334  			error = -ENOMEM;
335  			goto error0;
336  		}
337  
338  		if (xfs_sb_version_hascrc(&mp->m_sb))
339  			xfs_btree_init_block(mp, bp, XFS_ABTB_CRC_MAGIC, 0, 1,
340  						agno, XFS_BTREE_CRC_BLOCKS);
341  		else
342  			xfs_btree_init_block(mp, bp, XFS_ABTB_MAGIC, 0, 1,
343  						agno, 0);
344  
345  		arec = XFS_ALLOC_REC_ADDR(mp, XFS_BUF_TO_BLOCK(bp), 1);
346  		arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));
347  		arec->ar_blockcount = cpu_to_be32(
348  			agsize - be32_to_cpu(arec->ar_startblock));
349  
350  		error = xfs_bwrite(bp);
351  		xfs_buf_relse(bp);
352  		if (error)
353  			goto error0;
354  
355  		/*
356  		 * CNT btree root block
357  		 */
358  		bp = xfs_growfs_get_hdr_buf(mp,
359  				XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)),
360  				BTOBB(mp->m_sb.sb_blocksize), 0,
361  				&xfs_allocbt_buf_ops);
362  		if (!bp) {
363  			error = -ENOMEM;
364  			goto error0;
365  		}
366  
367  		if (xfs_sb_version_hascrc(&mp->m_sb))
368  			xfs_btree_init_block(mp, bp, XFS_ABTC_CRC_MAGIC, 0, 1,
369  						agno, XFS_BTREE_CRC_BLOCKS);
370  		else
371  			xfs_btree_init_block(mp, bp, XFS_ABTC_MAGIC, 0, 1,
372  						agno, 0);
373  
374  		arec = XFS_ALLOC_REC_ADDR(mp, XFS_BUF_TO_BLOCK(bp), 1);
375  		arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));
376  		arec->ar_blockcount = cpu_to_be32(
377  			agsize - be32_to_cpu(arec->ar_startblock));
378  		nfree += be32_to_cpu(arec->ar_blockcount);
379  
380  		error = xfs_bwrite(bp);
381  		xfs_buf_relse(bp);
382  		if (error)
383  			goto error0;
384  
385  		/*
386  		 * INO btree root block
387  		 */
388  		bp = xfs_growfs_get_hdr_buf(mp,
389  				XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)),
390  				BTOBB(mp->m_sb.sb_blocksize), 0,
391  				&xfs_inobt_buf_ops);
392  		if (!bp) {
393  			error = -ENOMEM;
394  			goto error0;
395  		}
396  
397  		if (xfs_sb_version_hascrc(&mp->m_sb))
398  			xfs_btree_init_block(mp, bp, XFS_IBT_CRC_MAGIC, 0, 0,
399  						agno, XFS_BTREE_CRC_BLOCKS);
400  		else
401  			xfs_btree_init_block(mp, bp, XFS_IBT_MAGIC, 0, 0,
402  						agno, 0);
403  
404  		error = xfs_bwrite(bp);
405  		xfs_buf_relse(bp);
406  		if (error)
407  			goto error0;
408  
409  		/*
410  		 * FINO btree root block
411  		 */
412  		if (xfs_sb_version_hasfinobt(&mp->m_sb)) {
413  			bp = xfs_growfs_get_hdr_buf(mp,
414  				XFS_AGB_TO_DADDR(mp, agno, XFS_FIBT_BLOCK(mp)),
415  				BTOBB(mp->m_sb.sb_blocksize), 0,
416  				&xfs_inobt_buf_ops);
417  			if (!bp) {
418  				error = -ENOMEM;
419  				goto error0;
420  			}
421  
422  			if (xfs_sb_version_hascrc(&mp->m_sb))
423  				xfs_btree_init_block(mp, bp, XFS_FIBT_CRC_MAGIC,
424  						     0, 0, agno,
425  						     XFS_BTREE_CRC_BLOCKS);
426  			else
427  				xfs_btree_init_block(mp, bp, XFS_FIBT_MAGIC, 0,
428  						     0, agno, 0);
429  
430  			error = xfs_bwrite(bp);
431  			xfs_buf_relse(bp);
432  			if (error)
433  				goto error0;
434  		}
435  
436  	}
437  	xfs_trans_agblocks_delta(tp, nfree);
438  	/*
439  	 * There are new blocks in the old last a.g.
440  	 */
441  	if (new) {
442  		/*
443  		 * Change the agi length.
444  		 */
445  		error = xfs_ialloc_read_agi(mp, tp, agno, &bp);
446  		if (error) {
447  			goto error0;
448  		}
449  		ASSERT(bp);
450  		agi = XFS_BUF_TO_AGI(bp);
451  		be32_add_cpu(&agi->agi_length, new);
452  		ASSERT(nagcount == oagcount ||
453  		       be32_to_cpu(agi->agi_length) == mp->m_sb.sb_agblocks);
454  		xfs_ialloc_log_agi(tp, bp, XFS_AGI_LENGTH);
455  		/*
456  		 * Change agf length.
457  		 */
458  		error = xfs_alloc_read_agf(mp, tp, agno, 0, &bp);
459  		if (error) {
460  			goto error0;
461  		}
462  		ASSERT(bp);
463  		agf = XFS_BUF_TO_AGF(bp);
464  		be32_add_cpu(&agf->agf_length, new);
465  		ASSERT(be32_to_cpu(agf->agf_length) ==
466  		       be32_to_cpu(agi->agi_length));
467  
468  		xfs_alloc_log_agf(tp, bp, XFS_AGF_LENGTH);
469  		/*
470  		 * Free the new space.
471  		 */
472  		error = xfs_free_extent(tp, XFS_AGB_TO_FSB(mp, agno,
473  			be32_to_cpu(agf->agf_length) - new), new);
474  		if (error) {
475  			goto error0;
476  		}
477  	}
478  
479  	/*
480  	 * Update changed superblock fields transactionally. These are not
481  	 * seen by the rest of the world until the transaction commit applies
482  	 * them atomically to the superblock.
483  	 */
484  	if (nagcount > oagcount)
485  		xfs_trans_mod_sb(tp, XFS_TRANS_SB_AGCOUNT, nagcount - oagcount);
486  	if (nb > mp->m_sb.sb_dblocks)
487  		xfs_trans_mod_sb(tp, XFS_TRANS_SB_DBLOCKS,
488  				 nb - mp->m_sb.sb_dblocks);
489  	if (nfree)
490  		xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, nfree);
491  	if (dpct)
492  		xfs_trans_mod_sb(tp, XFS_TRANS_SB_IMAXPCT, dpct);
493  	xfs_trans_set_sync(tp);
494  	error = xfs_trans_commit(tp);
495  	if (error)
496  		return error;
497  
498  	/* New allocation groups fully initialized, so update mount struct */
499  	if (nagimax)
500  		mp->m_maxagi = nagimax;
501  	if (mp->m_sb.sb_imax_pct) {
502  		__uint64_t icount = mp->m_sb.sb_dblocks * mp->m_sb.sb_imax_pct;
503  		do_div(icount, 100);
504  		mp->m_maxicount = icount << mp->m_sb.sb_inopblog;
505  	} else
506  		mp->m_maxicount = 0;
507  	xfs_set_low_space_thresholds(mp);
508  
509  	/* update secondary superblocks. */
510  	for (agno = 1; agno < nagcount; agno++) {
511  		error = 0;
512  		/*
513  		 * new secondary superblocks need to be zeroed, not read from
514  		 * disk as the contents of the new area we are growing into is
515  		 * completely unknown.
516  		 */
517  		if (agno < oagcount) {
518  			error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,
519  				  XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
520  				  XFS_FSS_TO_BB(mp, 1), 0, &bp,
521  				  &xfs_sb_buf_ops);
522  		} else {
523  			bp = xfs_trans_get_buf(NULL, mp->m_ddev_targp,
524  				  XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
525  				  XFS_FSS_TO_BB(mp, 1), 0);
526  			if (bp) {
527  				bp->b_ops = &xfs_sb_buf_ops;
528  				xfs_buf_zero(bp, 0, BBTOB(bp->b_length));
529  			} else
530  				error = -ENOMEM;
531  		}
532  
533  		/*
534  		 * If we get an error reading or writing alternate superblocks,
535  		 * continue.  xfs_repair chooses the "best" superblock based
536  		 * on most matches; if we break early, we'll leave more
537  		 * superblocks un-updated than updated, and xfs_repair may
538  		 * pick them over the properly-updated primary.
539  		 */
540  		if (error) {
541  			xfs_warn(mp,
542  		"error %d reading secondary superblock for ag %d",
543  				error, agno);
544  			saved_error = error;
545  			continue;
546  		}
547  		xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb);
548  
549  		error = xfs_bwrite(bp);
550  		xfs_buf_relse(bp);
551  		if (error) {
552  			xfs_warn(mp,
553  		"write error %d updating secondary superblock for ag %d",
554  				error, agno);
555  			saved_error = error;
556  			continue;
557  		}
558  	}
559  	return saved_error ? saved_error : error;
560  
561   error0:
562  	xfs_trans_cancel(tp);
563  	return error;
564  }
565  
566  static int
xfs_growfs_log_private(xfs_mount_t * mp,xfs_growfs_log_t * in)567  xfs_growfs_log_private(
568  	xfs_mount_t		*mp,	/* mount point for filesystem */
569  	xfs_growfs_log_t	*in)	/* growfs log input struct */
570  {
571  	xfs_extlen_t		nb;
572  
573  	nb = in->newblocks;
574  	if (nb < XFS_MIN_LOG_BLOCKS || nb < XFS_B_TO_FSB(mp, XFS_MIN_LOG_BYTES))
575  		return -EINVAL;
576  	if (nb == mp->m_sb.sb_logblocks &&
577  	    in->isint == (mp->m_sb.sb_logstart != 0))
578  		return -EINVAL;
579  	/*
580  	 * Moving the log is hard, need new interfaces to sync
581  	 * the log first, hold off all activity while moving it.
582  	 * Can have shorter or longer log in the same space,
583  	 * or transform internal to external log or vice versa.
584  	 */
585  	return -ENOSYS;
586  }
587  
588  /*
589   * protected versions of growfs function acquire and release locks on the mount
590   * point - exported through ioctls: XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG,
591   * XFS_IOC_FSGROWFSRT
592   */
593  
594  
595  int
xfs_growfs_data(xfs_mount_t * mp,xfs_growfs_data_t * in)596  xfs_growfs_data(
597  	xfs_mount_t		*mp,
598  	xfs_growfs_data_t	*in)
599  {
600  	int error;
601  
602  	if (!capable(CAP_SYS_ADMIN))
603  		return -EPERM;
604  	if (!mutex_trylock(&mp->m_growlock))
605  		return -EWOULDBLOCK;
606  	error = xfs_growfs_data_private(mp, in);
607  	/*
608  	 * Increment the generation unconditionally, the error could be from
609  	 * updating the secondary superblocks, in which case the new size
610  	 * is live already.
611  	 */
612  	mp->m_generation++;
613  	mutex_unlock(&mp->m_growlock);
614  	return error;
615  }
616  
617  int
xfs_growfs_log(xfs_mount_t * mp,xfs_growfs_log_t * in)618  xfs_growfs_log(
619  	xfs_mount_t		*mp,
620  	xfs_growfs_log_t	*in)
621  {
622  	int error;
623  
624  	if (!capable(CAP_SYS_ADMIN))
625  		return -EPERM;
626  	if (!mutex_trylock(&mp->m_growlock))
627  		return -EWOULDBLOCK;
628  	error = xfs_growfs_log_private(mp, in);
629  	mutex_unlock(&mp->m_growlock);
630  	return error;
631  }
632  
633  /*
634   * exported through ioctl XFS_IOC_FSCOUNTS
635   */
636  
637  int
xfs_fs_counts(xfs_mount_t * mp,xfs_fsop_counts_t * cnt)638  xfs_fs_counts(
639  	xfs_mount_t		*mp,
640  	xfs_fsop_counts_t	*cnt)
641  {
642  	cnt->allocino = percpu_counter_read_positive(&mp->m_icount);
643  	cnt->freeino = percpu_counter_read_positive(&mp->m_ifree);
644  	cnt->freedata = percpu_counter_read_positive(&mp->m_fdblocks) -
645  							XFS_ALLOC_SET_ASIDE(mp);
646  
647  	spin_lock(&mp->m_sb_lock);
648  	cnt->freertx = mp->m_sb.sb_frextents;
649  	spin_unlock(&mp->m_sb_lock);
650  	return 0;
651  }
652  
653  /*
654   * exported through ioctl XFS_IOC_SET_RESBLKS & XFS_IOC_GET_RESBLKS
655   *
656   * xfs_reserve_blocks is called to set m_resblks
657   * in the in-core mount table. The number of unused reserved blocks
658   * is kept in m_resblks_avail.
659   *
660   * Reserve the requested number of blocks if available. Otherwise return
661   * as many as possible to satisfy the request. The actual number
662   * reserved are returned in outval
663   *
664   * A null inval pointer indicates that only the current reserved blocks
665   * available  should  be returned no settings are changed.
666   */
667  
668  int
xfs_reserve_blocks(xfs_mount_t * mp,__uint64_t * inval,xfs_fsop_resblks_t * outval)669  xfs_reserve_blocks(
670  	xfs_mount_t             *mp,
671  	__uint64_t              *inval,
672  	xfs_fsop_resblks_t      *outval)
673  {
674  	__int64_t		lcounter, delta, fdblks_delta;
675  	__uint64_t		request;
676  
677  	/* If inval is null, report current values and return */
678  	if (inval == (__uint64_t *)NULL) {
679  		if (!outval)
680  			return -EINVAL;
681  		outval->resblks = mp->m_resblks;
682  		outval->resblks_avail = mp->m_resblks_avail;
683  		return 0;
684  	}
685  
686  	request = *inval;
687  
688  	/*
689  	 * With per-cpu counters, this becomes an interesting
690  	 * problem. we needto work out if we are freeing or allocation
691  	 * blocks first, then we can do the modification as necessary.
692  	 *
693  	 * We do this under the m_sb_lock so that if we are near
694  	 * ENOSPC, we will hold out any changes while we work out
695  	 * what to do. This means that the amount of free space can
696  	 * change while we do this, so we need to retry if we end up
697  	 * trying to reserve more space than is available.
698  	 */
699  retry:
700  	spin_lock(&mp->m_sb_lock);
701  
702  	/*
703  	 * If our previous reservation was larger than the current value,
704  	 * then move any unused blocks back to the free pool.
705  	 */
706  	fdblks_delta = 0;
707  	if (mp->m_resblks > request) {
708  		lcounter = mp->m_resblks_avail - request;
709  		if (lcounter  > 0) {		/* release unused blocks */
710  			fdblks_delta = lcounter;
711  			mp->m_resblks_avail -= lcounter;
712  		}
713  		mp->m_resblks = request;
714  	} else {
715  		__int64_t	free;
716  
717  		free = percpu_counter_sum(&mp->m_fdblocks) -
718  							XFS_ALLOC_SET_ASIDE(mp);
719  		if (!free)
720  			goto out; /* ENOSPC and fdblks_delta = 0 */
721  
722  		delta = request - mp->m_resblks;
723  		lcounter = free - delta;
724  		if (lcounter < 0) {
725  			/* We can't satisfy the request, just get what we can */
726  			mp->m_resblks += free;
727  			mp->m_resblks_avail += free;
728  			fdblks_delta = -free;
729  		} else {
730  			fdblks_delta = -delta;
731  			mp->m_resblks = request;
732  			mp->m_resblks_avail += delta;
733  		}
734  	}
735  out:
736  	if (outval) {
737  		outval->resblks = mp->m_resblks;
738  		outval->resblks_avail = mp->m_resblks_avail;
739  	}
740  	spin_unlock(&mp->m_sb_lock);
741  
742  	if (fdblks_delta) {
743  		/*
744  		 * If we are putting blocks back here, m_resblks_avail is
745  		 * already at its max so this will put it in the free pool.
746  		 *
747  		 * If we need space, we'll either succeed in getting it
748  		 * from the free block count or we'll get an enospc. If
749  		 * we get a ENOSPC, it means things changed while we were
750  		 * calculating fdblks_delta and so we should try again to
751  		 * see if there is anything left to reserve.
752  		 *
753  		 * Don't set the reserved flag here - we don't want to reserve
754  		 * the extra reserve blocks from the reserve.....
755  		 */
756  		int error;
757  		error = xfs_mod_fdblocks(mp, fdblks_delta, 0);
758  		if (error == -ENOSPC)
759  			goto retry;
760  	}
761  	return 0;
762  }
763  
764  int
xfs_fs_goingdown(xfs_mount_t * mp,__uint32_t inflags)765  xfs_fs_goingdown(
766  	xfs_mount_t	*mp,
767  	__uint32_t	inflags)
768  {
769  	switch (inflags) {
770  	case XFS_FSOP_GOING_FLAGS_DEFAULT: {
771  		struct super_block *sb = freeze_bdev(mp->m_super->s_bdev);
772  
773  		if (sb && !IS_ERR(sb)) {
774  			xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT);
775  			thaw_bdev(sb->s_bdev, sb);
776  		}
777  
778  		break;
779  	}
780  	case XFS_FSOP_GOING_FLAGS_LOGFLUSH:
781  		xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT);
782  		break;
783  	case XFS_FSOP_GOING_FLAGS_NOLOGFLUSH:
784  		xfs_force_shutdown(mp,
785  				SHUTDOWN_FORCE_UMOUNT | SHUTDOWN_LOG_IO_ERROR);
786  		break;
787  	default:
788  		return -EINVAL;
789  	}
790  
791  	return 0;
792  }
793  
794  /*
795   * Force a shutdown of the filesystem instantly while keeping the filesystem
796   * consistent. We don't do an unmount here; just shutdown the shop, make sure
797   * that absolutely nothing persistent happens to this filesystem after this
798   * point.
799   */
800  void
xfs_do_force_shutdown(xfs_mount_t * mp,int flags,char * fname,int lnnum)801  xfs_do_force_shutdown(
802  	xfs_mount_t	*mp,
803  	int		flags,
804  	char		*fname,
805  	int		lnnum)
806  {
807  	int		logerror;
808  
809  	logerror = flags & SHUTDOWN_LOG_IO_ERROR;
810  
811  	if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
812  		xfs_notice(mp,
813  	"%s(0x%x) called from line %d of file %s.  Return address = 0x%p",
814  			__func__, flags, lnnum, fname, __return_address);
815  	}
816  	/*
817  	 * No need to duplicate efforts.
818  	 */
819  	if (XFS_FORCED_SHUTDOWN(mp) && !logerror)
820  		return;
821  
822  	/*
823  	 * This flags XFS_MOUNT_FS_SHUTDOWN, makes sure that we don't
824  	 * queue up anybody new on the log reservations, and wakes up
825  	 * everybody who's sleeping on log reservations to tell them
826  	 * the bad news.
827  	 */
828  	if (xfs_log_force_umount(mp, logerror))
829  		return;
830  
831  	if (flags & SHUTDOWN_CORRUPT_INCORE) {
832  		xfs_alert_tag(mp, XFS_PTAG_SHUTDOWN_CORRUPT,
833      "Corruption of in-memory data detected.  Shutting down filesystem");
834  		if (XFS_ERRLEVEL_HIGH <= xfs_error_level)
835  			xfs_stack_trace();
836  	} else if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
837  		if (logerror) {
838  			xfs_alert_tag(mp, XFS_PTAG_SHUTDOWN_LOGERROR,
839  		"Log I/O Error Detected.  Shutting down filesystem");
840  		} else if (flags & SHUTDOWN_DEVICE_REQ) {
841  			xfs_alert_tag(mp, XFS_PTAG_SHUTDOWN_IOERROR,
842  		"All device paths lost.  Shutting down filesystem");
843  		} else if (!(flags & SHUTDOWN_REMOTE_REQ)) {
844  			xfs_alert_tag(mp, XFS_PTAG_SHUTDOWN_IOERROR,
845  		"I/O Error Detected. Shutting down filesystem");
846  		}
847  	}
848  	if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
849  		xfs_alert(mp,
850  	"Please umount the filesystem and rectify the problem(s)");
851  	}
852  }
853