aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_sb.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2014-06-25 00:57:22 -0400
committerDave Chinner <david@fromorbit.com>2014-06-25 00:57:22 -0400
commit69116a1317ce3d2292e062bfb1a22757b95dcd06 (patch)
treeeae7363c9e70d9364882390b5b4730f49f12c6cd /fs/xfs/xfs_sb.c
parentb474c7ae4395ba684e85fde8f55c8cf44a39afaf (diff)
xfs: create libxfs infrastructure
To minimise the differences between kernel and userspace code, split the kernel code into the same structure as the userspace code. That is, the gneric core functionality of XFS is moved to a libxfs/ directory and treat it as a layering barrier in the XFS code. This patch introduces the libxfs directory, the build infrastructure and an initial source and header file to build. The libxfs directory will contain the header files that are needed to build libxfs - most of userspace does not care about the location of these header files as they are accessed indirectly. Hence keeping them inside libxfs makes it easy to track the changes and script the sync process as the directory structure will be identical. To allow this changeover to occur in the kernel code, there are some temporary infrastructure in the makefiles to grab the header filesystem from both locations. Once all the files are moved, modifications will be made in the source code that will make the need for these include directives go away. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/xfs_sb.c')
-rw-r--r--fs/xfs/xfs_sb.c819
1 files changed, 0 insertions, 819 deletions
diff --git a/fs/xfs/xfs_sb.c b/fs/xfs/xfs_sb.c
deleted file mode 100644
index 06ad60b4b9fd..000000000000
--- a/fs/xfs/xfs_sb.c
+++ /dev/null
@@ -1,819 +0,0 @@
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_bit.h"
25#include "xfs_sb.h"
26#include "xfs_ag.h"
27#include "xfs_mount.h"
28#include "xfs_inode.h"
29#include "xfs_ialloc.h"
30#include "xfs_alloc.h"
31#include "xfs_error.h"
32#include "xfs_trace.h"
33#include "xfs_cksum.h"
34#include "xfs_trans.h"
35#include "xfs_buf_item.h"
36#include "xfs_dinode.h"
37#include "xfs_bmap_btree.h"
38#include "xfs_alloc_btree.h"
39#include "xfs_ialloc_btree.h"
40
41/*
42 * Physical superblock buffer manipulations. Shared with libxfs in userspace.
43 */
44
45static const struct {
46 short offset;
47 short type; /* 0 = integer
48 * 1 = binary / string (no translation)
49 */
50} xfs_sb_info[] = {
51 { offsetof(xfs_sb_t, sb_magicnum), 0 },
52 { offsetof(xfs_sb_t, sb_blocksize), 0 },
53 { offsetof(xfs_sb_t, sb_dblocks), 0 },
54 { offsetof(xfs_sb_t, sb_rblocks), 0 },
55 { offsetof(xfs_sb_t, sb_rextents), 0 },
56 { offsetof(xfs_sb_t, sb_uuid), 1 },
57 { offsetof(xfs_sb_t, sb_logstart), 0 },
58 { offsetof(xfs_sb_t, sb_rootino), 0 },
59 { offsetof(xfs_sb_t, sb_rbmino), 0 },
60 { offsetof(xfs_sb_t, sb_rsumino), 0 },
61 { offsetof(xfs_sb_t, sb_rextsize), 0 },
62 { offsetof(xfs_sb_t, sb_agblocks), 0 },
63 { offsetof(xfs_sb_t, sb_agcount), 0 },
64 { offsetof(xfs_sb_t, sb_rbmblocks), 0 },
65 { offsetof(xfs_sb_t, sb_logblocks), 0 },
66 { offsetof(xfs_sb_t, sb_versionnum), 0 },
67 { offsetof(xfs_sb_t, sb_sectsize), 0 },
68 { offsetof(xfs_sb_t, sb_inodesize), 0 },
69 { offsetof(xfs_sb_t, sb_inopblock), 0 },
70 { offsetof(xfs_sb_t, sb_fname[0]), 1 },
71 { offsetof(xfs_sb_t, sb_blocklog), 0 },
72 { offsetof(xfs_sb_t, sb_sectlog), 0 },
73 { offsetof(xfs_sb_t, sb_inodelog), 0 },
74 { offsetof(xfs_sb_t, sb_inopblog), 0 },
75 { offsetof(xfs_sb_t, sb_agblklog), 0 },
76 { offsetof(xfs_sb_t, sb_rextslog), 0 },
77 { offsetof(xfs_sb_t, sb_inprogress), 0 },
78 { offsetof(xfs_sb_t, sb_imax_pct), 0 },
79 { offsetof(xfs_sb_t, sb_icount), 0 },
80 { offsetof(xfs_sb_t, sb_ifree), 0 },
81 { offsetof(xfs_sb_t, sb_fdblocks), 0 },
82 { offsetof(xfs_sb_t, sb_frextents), 0 },
83 { offsetof(xfs_sb_t, sb_uquotino), 0 },
84 { offsetof(xfs_sb_t, sb_gquotino), 0 },
85 { offsetof(xfs_sb_t, sb_qflags), 0 },
86 { offsetof(xfs_sb_t, sb_flags), 0 },
87 { offsetof(xfs_sb_t, sb_shared_vn), 0 },
88 { offsetof(xfs_sb_t, sb_inoalignmt), 0 },
89 { offsetof(xfs_sb_t, sb_unit), 0 },
90 { offsetof(xfs_sb_t, sb_width), 0 },
91 { offsetof(xfs_sb_t, sb_dirblklog), 0 },
92 { offsetof(xfs_sb_t, sb_logsectlog), 0 },
93 { offsetof(xfs_sb_t, sb_logsectsize), 0 },
94 { offsetof(xfs_sb_t, sb_logsunit), 0 },
95 { offsetof(xfs_sb_t, sb_features2), 0 },
96 { offsetof(xfs_sb_t, sb_bad_features2), 0 },
97 { offsetof(xfs_sb_t, sb_features_compat), 0 },
98 { offsetof(xfs_sb_t, sb_features_ro_compat), 0 },
99 { offsetof(xfs_sb_t, sb_features_incompat), 0 },
100 { offsetof(xfs_sb_t, sb_features_log_incompat), 0 },
101 { offsetof(xfs_sb_t, sb_crc), 0 },
102 { offsetof(xfs_sb_t, sb_pad), 0 },
103 { offsetof(xfs_sb_t, sb_pquotino), 0 },
104 { offsetof(xfs_sb_t, sb_lsn), 0 },
105 { sizeof(xfs_sb_t), 0 }
106};
107
108/*
109 * Reference counting access wrappers to the perag structures.
110 * Because we never free per-ag structures, the only thing we
111 * have to protect against changes is the tree structure itself.
112 */
113struct xfs_perag *
114xfs_perag_get(
115 struct xfs_mount *mp,
116 xfs_agnumber_t agno)
117{
118 struct xfs_perag *pag;
119 int ref = 0;
120
121 rcu_read_lock();
122 pag = radix_tree_lookup(&mp->m_perag_tree, agno);
123 if (pag) {
124 ASSERT(atomic_read(&pag->pag_ref) >= 0);
125 ref = atomic_inc_return(&pag->pag_ref);
126 }
127 rcu_read_unlock();
128 trace_xfs_perag_get(mp, agno, ref, _RET_IP_);
129 return pag;
130}
131
132/*
133 * search from @first to find the next perag with the given tag set.
134 */
135struct xfs_perag *
136xfs_perag_get_tag(
137 struct xfs_mount *mp,
138 xfs_agnumber_t first,
139 int tag)
140{
141 struct xfs_perag *pag;
142 int found;
143 int ref;
144
145 rcu_read_lock();
146 found = radix_tree_gang_lookup_tag(&mp->m_perag_tree,
147 (void **)&pag, first, 1, tag);
148 if (found <= 0) {
149 rcu_read_unlock();
150 return NULL;
151 }
152 ref = atomic_inc_return(&pag->pag_ref);
153 rcu_read_unlock();
154 trace_xfs_perag_get_tag(mp, pag->pag_agno, ref, _RET_IP_);
155 return pag;
156}
157
158void
159xfs_perag_put(
160 struct xfs_perag *pag)
161{
162 int ref;
163
164 ASSERT(atomic_read(&pag->pag_ref) > 0);
165 ref = atomic_dec_return(&pag->pag_ref);
166 trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_);
167}
168
169/*
170 * Check the validity of the SB found.
171 */
172STATIC int
173xfs_mount_validate_sb(
174 xfs_mount_t *mp,
175 xfs_sb_t *sbp,
176 bool check_inprogress,
177 bool check_version)
178{
179
180 /*
181 * If the log device and data device have the
182 * same device number, the log is internal.
183 * Consequently, the sb_logstart should be non-zero. If
184 * we have a zero sb_logstart in this case, we may be trying to mount
185 * a volume filesystem in a non-volume manner.
186 */
187 if (sbp->sb_magicnum != XFS_SB_MAGIC) {
188 xfs_warn(mp, "bad magic number");
189 return EWRONGFS;
190 }
191
192
193 if (!xfs_sb_good_version(sbp)) {
194 xfs_warn(mp, "bad version");
195 return EWRONGFS;
196 }
197
198 /*
199 * Version 5 superblock feature mask validation. Reject combinations the
200 * kernel cannot support up front before checking anything else. For
201 * write validation, we don't need to check feature masks.
202 */
203 if (check_version && XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) {
204 if (xfs_sb_has_compat_feature(sbp,
205 XFS_SB_FEAT_COMPAT_UNKNOWN)) {
206 xfs_warn(mp,
207"Superblock has unknown compatible features (0x%x) enabled.\n"
208"Using a more recent kernel is recommended.",
209 (sbp->sb_features_compat &
210 XFS_SB_FEAT_COMPAT_UNKNOWN));
211 }
212
213 if (xfs_sb_has_ro_compat_feature(sbp,
214 XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) {
215 xfs_alert(mp,
216"Superblock has unknown read-only compatible features (0x%x) enabled.",
217 (sbp->sb_features_ro_compat &
218 XFS_SB_FEAT_RO_COMPAT_UNKNOWN));
219 if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {
220 xfs_warn(mp,
221"Attempted to mount read-only compatible filesystem read-write.\n"
222"Filesystem can only be safely mounted read only.");
223 return EINVAL;
224 }
225 }
226 if (xfs_sb_has_incompat_feature(sbp,
227 XFS_SB_FEAT_INCOMPAT_UNKNOWN)) {
228 xfs_warn(mp,
229"Superblock has unknown incompatible features (0x%x) enabled.\n"
230"Filesystem can not be safely mounted by this kernel.",
231 (sbp->sb_features_incompat &
232 XFS_SB_FEAT_INCOMPAT_UNKNOWN));
233 return EINVAL;
234 }
235 }
236
237 if (xfs_sb_version_has_pquotino(sbp)) {
238 if (sbp->sb_qflags & (XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD)) {
239 xfs_notice(mp,
240 "Version 5 of Super block has XFS_OQUOTA bits.");
241 return EFSCORRUPTED;
242 }
243 } else if (sbp->sb_qflags & (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD |
244 XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD)) {
245 xfs_notice(mp,
246"Superblock earlier than Version 5 has XFS_[PQ]UOTA_{ENFD|CHKD} bits.");
247 return EFSCORRUPTED;
248 }
249
250 if (unlikely(
251 sbp->sb_logstart == 0 && mp->m_logdev_targp == mp->m_ddev_targp)) {
252 xfs_warn(mp,
253 "filesystem is marked as having an external log; "
254 "specify logdev on the mount command line.");
255 return EINVAL;
256 }
257
258 if (unlikely(
259 sbp->sb_logstart != 0 && mp->m_logdev_targp != mp->m_ddev_targp)) {
260 xfs_warn(mp,
261 "filesystem is marked as having an internal log; "
262 "do not specify logdev on the mount command line.");
263 return EINVAL;
264 }
265
266 /*
267 * More sanity checking. Most of these were stolen directly from
268 * xfs_repair.
269 */
270 if (unlikely(
271 sbp->sb_agcount <= 0 ||
272 sbp->sb_sectsize < XFS_MIN_SECTORSIZE ||
273 sbp->sb_sectsize > XFS_MAX_SECTORSIZE ||
274 sbp->sb_sectlog < XFS_MIN_SECTORSIZE_LOG ||
275 sbp->sb_sectlog > XFS_MAX_SECTORSIZE_LOG ||
276 sbp->sb_sectsize != (1 << sbp->sb_sectlog) ||
277 sbp->sb_blocksize < XFS_MIN_BLOCKSIZE ||
278 sbp->sb_blocksize > XFS_MAX_BLOCKSIZE ||
279 sbp->sb_blocklog < XFS_MIN_BLOCKSIZE_LOG ||
280 sbp->sb_blocklog > XFS_MAX_BLOCKSIZE_LOG ||
281 sbp->sb_blocksize != (1 << sbp->sb_blocklog) ||
282 sbp->sb_inodesize < XFS_DINODE_MIN_SIZE ||
283 sbp->sb_inodesize > XFS_DINODE_MAX_SIZE ||
284 sbp->sb_inodelog < XFS_DINODE_MIN_LOG ||
285 sbp->sb_inodelog > XFS_DINODE_MAX_LOG ||
286 sbp->sb_inodesize != (1 << sbp->sb_inodelog) ||
287 sbp->sb_inopblock != howmany(sbp->sb_blocksize,sbp->sb_inodesize) ||
288 (sbp->sb_blocklog - sbp->sb_inodelog != sbp->sb_inopblog) ||
289 (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE) ||
290 (sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) ||
291 (sbp->sb_imax_pct > 100 /* zero sb_imax_pct is valid */) ||
292 sbp->sb_dblocks == 0 ||
293 sbp->sb_dblocks > XFS_MAX_DBLOCKS(sbp) ||
294 sbp->sb_dblocks < XFS_MIN_DBLOCKS(sbp) ||
295 sbp->sb_shared_vn != 0)) {
296 xfs_notice(mp, "SB sanity check failed");
297 return EFSCORRUPTED;
298 }
299
300 /*
301 * Until this is fixed only page-sized or smaller data blocks work.
302 */
303 if (unlikely(sbp->sb_blocksize > PAGE_SIZE)) {
304 xfs_warn(mp,
305 "File system with blocksize %d bytes. "
306 "Only pagesize (%ld) or less will currently work.",
307 sbp->sb_blocksize, PAGE_SIZE);
308 return ENOSYS;
309 }
310
311 /*
312 * Currently only very few inode sizes are supported.
313 */
314 switch (sbp->sb_inodesize) {
315 case 256:
316 case 512:
317 case 1024:
318 case 2048:
319 break;
320 default:
321 xfs_warn(mp, "inode size of %d bytes not supported",
322 sbp->sb_inodesize);
323 return ENOSYS;
324 }
325
326 if (xfs_sb_validate_fsb_count(sbp, sbp->sb_dblocks) ||
327 xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) {
328 xfs_warn(mp,
329 "file system too large to be mounted on this system.");
330 return EFBIG;
331 }
332
333 if (check_inprogress && sbp->sb_inprogress) {
334 xfs_warn(mp, "Offline file system operation in progress!");
335 return EFSCORRUPTED;
336 }
337 return 0;
338}
339
340void
341xfs_sb_quota_from_disk(struct xfs_sb *sbp)
342{
343 /*
344 * older mkfs doesn't initialize quota inodes to NULLFSINO. This
345 * leads to in-core values having two different values for a quota
346 * inode to be invalid: 0 and NULLFSINO. Change it to a single value
347 * NULLFSINO.
348 *
349 * Note that this change affect only the in-core values. These
350 * values are not written back to disk unless any quota information
351 * is written to the disk. Even in that case, sb_pquotino field is
352 * not written to disk unless the superblock supports pquotino.
353 */
354 if (sbp->sb_uquotino == 0)
355 sbp->sb_uquotino = NULLFSINO;
356 if (sbp->sb_gquotino == 0)
357 sbp->sb_gquotino = NULLFSINO;
358 if (sbp->sb_pquotino == 0)
359 sbp->sb_pquotino = NULLFSINO;
360
361 /*
362 * We need to do these manipilations only if we are working
363 * with an older version of on-disk superblock.
364 */
365 if (xfs_sb_version_has_pquotino(sbp))
366 return;
367
368 if (sbp->sb_qflags & XFS_OQUOTA_ENFD)
369 sbp->sb_qflags |= (sbp->sb_qflags & XFS_PQUOTA_ACCT) ?
370 XFS_PQUOTA_ENFD : XFS_GQUOTA_ENFD;
371 if (sbp->sb_qflags & XFS_OQUOTA_CHKD)
372 sbp->sb_qflags |= (sbp->sb_qflags & XFS_PQUOTA_ACCT) ?
373 XFS_PQUOTA_CHKD : XFS_GQUOTA_CHKD;
374 sbp->sb_qflags &= ~(XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD);
375
376 if (sbp->sb_qflags & XFS_PQUOTA_ACCT) {
377 /*
378 * In older version of superblock, on-disk superblock only
379 * has sb_gquotino, and in-core superblock has both sb_gquotino
380 * and sb_pquotino. But, only one of them is supported at any
381 * point of time. So, if PQUOTA is set in disk superblock,
382 * copy over sb_gquotino to sb_pquotino.
383 */
384 sbp->sb_pquotino = sbp->sb_gquotino;
385 sbp->sb_gquotino = NULLFSINO;
386 }
387}
388
389void
390xfs_sb_from_disk(
391 struct xfs_sb *to,
392 xfs_dsb_t *from)
393{
394 to->sb_magicnum = be32_to_cpu(from->sb_magicnum);
395 to->sb_blocksize = be32_to_cpu(from->sb_blocksize);
396 to->sb_dblocks = be64_to_cpu(from->sb_dblocks);
397 to->sb_rblocks = be64_to_cpu(from->sb_rblocks);
398 to->sb_rextents = be64_to_cpu(from->sb_rextents);
399 memcpy(&to->sb_uuid, &from->sb_uuid, sizeof(to->sb_uuid));
400 to->sb_logstart = be64_to_cpu(from->sb_logstart);
401 to->sb_rootino = be64_to_cpu(from->sb_rootino);
402 to->sb_rbmino = be64_to_cpu(from->sb_rbmino);
403 to->sb_rsumino = be64_to_cpu(from->sb_rsumino);
404 to->sb_rextsize = be32_to_cpu(from->sb_rextsize);
405 to->sb_agblocks = be32_to_cpu(from->sb_agblocks);
406 to->sb_agcount = be32_to_cpu(from->sb_agcount);
407 to->sb_rbmblocks = be32_to_cpu(from->sb_rbmblocks);
408 to->sb_logblocks = be32_to_cpu(from->sb_logblocks);
409 to->sb_versionnum = be16_to_cpu(from->sb_versionnum);
410 to->sb_sectsize = be16_to_cpu(from->sb_sectsize);
411 to->sb_inodesize = be16_to_cpu(from->sb_inodesize);
412 to->sb_inopblock = be16_to_cpu(from->sb_inopblock);
413 memcpy(&to->sb_fname, &from->sb_fname, sizeof(to->sb_fname));
414 to->sb_blocklog = from->sb_blocklog;
415 to->sb_sectlog = from->sb_sectlog;
416 to->sb_inodelog = from->sb_inodelog;
417 to->sb_inopblog = from->sb_inopblog;
418 to->sb_agblklog = from->sb_agblklog;
419 to->sb_rextslog = from->sb_rextslog;
420 to->sb_inprogress = from->sb_inprogress;
421 to->sb_imax_pct = from->sb_imax_pct;
422 to->sb_icount = be64_to_cpu(from->sb_icount);
423 to->sb_ifree = be64_to_cpu(from->sb_ifree);
424 to->sb_fdblocks = be64_to_cpu(from->sb_fdblocks);
425 to->sb_frextents = be64_to_cpu(from->sb_frextents);
426 to->sb_uquotino = be64_to_cpu(from->sb_uquotino);
427 to->sb_gquotino = be64_to_cpu(from->sb_gquotino);
428 to->sb_qflags = be16_to_cpu(from->sb_qflags);
429 to->sb_flags = from->sb_flags;
430 to->sb_shared_vn = from->sb_shared_vn;
431 to->sb_inoalignmt = be32_to_cpu(from->sb_inoalignmt);
432 to->sb_unit = be32_to_cpu(from->sb_unit);
433 to->sb_width = be32_to_cpu(from->sb_width);
434 to->sb_dirblklog = from->sb_dirblklog;
435 to->sb_logsectlog = from->sb_logsectlog;
436 to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize);
437 to->sb_logsunit = be32_to_cpu(from->sb_logsunit);
438 to->sb_features2 = be32_to_cpu(from->sb_features2);
439 to->sb_bad_features2 = be32_to_cpu(from->sb_bad_features2);
440 to->sb_features_compat = be32_to_cpu(from->sb_features_compat);
441 to->sb_features_ro_compat = be32_to_cpu(from->sb_features_ro_compat);
442 to->sb_features_incompat = be32_to_cpu(from->sb_features_incompat);
443 to->sb_features_log_incompat =
444 be32_to_cpu(from->sb_features_log_incompat);
445 to->sb_pad = 0;
446 to->sb_pquotino = be64_to_cpu(from->sb_pquotino);
447 to->sb_lsn = be64_to_cpu(from->sb_lsn);
448}
449
450static inline void
451xfs_sb_quota_to_disk(
452 xfs_dsb_t *to,
453 xfs_sb_t *from,
454 __int64_t *fields)
455{
456 __uint16_t qflags = from->sb_qflags;
457
458 /*
459 * We need to do these manipilations only if we are working
460 * with an older version of on-disk superblock.
461 */
462 if (xfs_sb_version_has_pquotino(from))
463 return;
464
465 if (*fields & XFS_SB_QFLAGS) {
466 /*
467 * The in-core version of sb_qflags do not have
468 * XFS_OQUOTA_* flags, whereas the on-disk version
469 * does. So, convert incore XFS_{PG}QUOTA_* flags
470 * to on-disk XFS_OQUOTA_* flags.
471 */
472 qflags &= ~(XFS_PQUOTA_ENFD | XFS_PQUOTA_CHKD |
473 XFS_GQUOTA_ENFD | XFS_GQUOTA_CHKD);
474
475 if (from->sb_qflags &
476 (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD))
477 qflags |= XFS_OQUOTA_ENFD;
478 if (from->sb_qflags &
479 (XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD))
480 qflags |= XFS_OQUOTA_CHKD;
481 to->sb_qflags = cpu_to_be16(qflags);
482 *fields &= ~XFS_SB_QFLAGS;
483 }
484
485 /*
486 * GQUOTINO and PQUOTINO cannot be used together in versions
487 * of superblock that do not have pquotino. from->sb_flags
488 * tells us which quota is active and should be copied to
489 * disk.
490 */
491 if ((*fields & XFS_SB_GQUOTINO) &&
492 (from->sb_qflags & XFS_GQUOTA_ACCT))
493 to->sb_gquotino = cpu_to_be64(from->sb_gquotino);
494 else if ((*fields & XFS_SB_PQUOTINO) &&
495 (from->sb_qflags & XFS_PQUOTA_ACCT))
496 to->sb_gquotino = cpu_to_be64(from->sb_pquotino);
497
498 *fields &= ~(XFS_SB_PQUOTINO | XFS_SB_GQUOTINO);
499}
500
501/*
502 * Copy in core superblock to ondisk one.
503 *
504 * The fields argument is mask of superblock fields to copy.
505 */
506void
507xfs_sb_to_disk(
508 xfs_dsb_t *to,
509 xfs_sb_t *from,
510 __int64_t fields)
511{
512 xfs_caddr_t to_ptr = (xfs_caddr_t)to;
513 xfs_caddr_t from_ptr = (xfs_caddr_t)from;
514 xfs_sb_field_t f;
515 int first;
516 int size;
517
518 ASSERT(fields);
519 if (!fields)
520 return;
521
522 xfs_sb_quota_to_disk(to, from, &fields);
523 while (fields) {
524 f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
525 first = xfs_sb_info[f].offset;
526 size = xfs_sb_info[f + 1].offset - first;
527
528 ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1);
529
530 if (size == 1 || xfs_sb_info[f].type == 1) {
531 memcpy(to_ptr + first, from_ptr + first, size);
532 } else {
533 switch (size) {
534 case 2:
535 *(__be16 *)(to_ptr + first) =
536 cpu_to_be16(*(__u16 *)(from_ptr + first));
537 break;
538 case 4:
539 *(__be32 *)(to_ptr + first) =
540 cpu_to_be32(*(__u32 *)(from_ptr + first));
541 break;
542 case 8:
543 *(__be64 *)(to_ptr + first) =
544 cpu_to_be64(*(__u64 *)(from_ptr + first));
545 break;
546 default:
547 ASSERT(0);
548 }
549 }
550
551 fields &= ~(1LL << f);
552 }
553}
554
555static int
556xfs_sb_verify(
557 struct xfs_buf *bp,
558 bool check_version)
559{
560 struct xfs_mount *mp = bp->b_target->bt_mount;
561 struct xfs_sb sb;
562
563 xfs_sb_from_disk(&sb, XFS_BUF_TO_SBP(bp));
564
565 /*
566 * Only check the in progress field for the primary superblock as
567 * mkfs.xfs doesn't clear it from secondary superblocks.
568 */
569 return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR,
570 check_version);
571}
572
573/*
574 * If the superblock has the CRC feature bit set or the CRC field is non-null,
575 * check that the CRC is valid. We check the CRC field is non-null because a
576 * single bit error could clear the feature bit and unused parts of the
577 * superblock are supposed to be zero. Hence a non-null crc field indicates that
578 * we've potentially lost a feature bit and we should check it anyway.
579 *
580 * However, past bugs (i.e. in growfs) left non-zeroed regions beyond the
581 * last field in V4 secondary superblocks. So for secondary superblocks,
582 * we are more forgiving, and ignore CRC failures if the primary doesn't
583 * indicate that the fs version is V5.
584 */
585static void
586xfs_sb_read_verify(
587 struct xfs_buf *bp)
588{
589 struct xfs_mount *mp = bp->b_target->bt_mount;
590 struct xfs_dsb *dsb = XFS_BUF_TO_SBP(bp);
591 int error;
592
593 /*
594 * open code the version check to avoid needing to convert the entire
595 * superblock from disk order just to check the version number
596 */
597 if (dsb->sb_magicnum == cpu_to_be32(XFS_SB_MAGIC) &&
598 (((be16_to_cpu(dsb->sb_versionnum) & XFS_SB_VERSION_NUMBITS) ==
599 XFS_SB_VERSION_5) ||
600 dsb->sb_crc != 0)) {
601
602 if (!xfs_buf_verify_cksum(bp, XFS_SB_CRC_OFF)) {
603 /* Only fail bad secondaries on a known V5 filesystem */
604 if (bp->b_bn == XFS_SB_DADDR ||
605 xfs_sb_version_hascrc(&mp->m_sb)) {
606 error = EFSBADCRC;
607 goto out_error;
608 }
609 }
610 }
611 error = xfs_sb_verify(bp, true);
612
613out_error:
614 if (error) {
615 xfs_buf_ioerror(bp, error);
616 if (error == EFSCORRUPTED || error == EFSBADCRC)
617 xfs_verifier_error(bp);
618 }
619}
620
621/*
622 * We may be probed for a filesystem match, so we may not want to emit
623 * messages when the superblock buffer is not actually an XFS superblock.
624 * If we find an XFS superblock, then run a normal, noisy mount because we are
625 * really going to mount it and want to know about errors.
626 */
627static void
628xfs_sb_quiet_read_verify(
629 struct xfs_buf *bp)
630{
631 struct xfs_dsb *dsb = XFS_BUF_TO_SBP(bp);
632
633 if (dsb->sb_magicnum == cpu_to_be32(XFS_SB_MAGIC)) {
634 /* XFS filesystem, verify noisily! */
635 xfs_sb_read_verify(bp);
636 return;
637 }
638 /* quietly fail */
639 xfs_buf_ioerror(bp, EWRONGFS);
640}
641
642static void
643xfs_sb_write_verify(
644 struct xfs_buf *bp)
645{
646 struct xfs_mount *mp = bp->b_target->bt_mount;
647 struct xfs_buf_log_item *bip = bp->b_fspriv;
648 int error;
649
650 error = xfs_sb_verify(bp, false);
651 if (error) {
652 xfs_buf_ioerror(bp, error);
653 xfs_verifier_error(bp);
654 return;
655 }
656
657 if (!xfs_sb_version_hascrc(&mp->m_sb))
658 return;
659
660 if (bip)
661 XFS_BUF_TO_SBP(bp)->sb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
662
663 xfs_buf_update_cksum(bp, XFS_SB_CRC_OFF);
664}
665
666const struct xfs_buf_ops xfs_sb_buf_ops = {
667 .verify_read = xfs_sb_read_verify,
668 .verify_write = xfs_sb_write_verify,
669};
670
671const struct xfs_buf_ops xfs_sb_quiet_buf_ops = {
672 .verify_read = xfs_sb_quiet_read_verify,
673 .verify_write = xfs_sb_write_verify,
674};
675
676/*
677 * xfs_mount_common
678 *
679 * Mount initialization code establishing various mount
680 * fields from the superblock associated with the given
681 * mount structure
682 */
683void
684xfs_sb_mount_common(
685 struct xfs_mount *mp,
686 struct xfs_sb *sbp)
687{
688 mp->m_agfrotor = mp->m_agirotor = 0;
689 spin_lock_init(&mp->m_agirotor_lock);
690 mp->m_maxagi = mp->m_sb.sb_agcount;
691 mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG;
692 mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
693 mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
694 mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1;
695 mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
696 mp->m_blockmask = sbp->sb_blocksize - 1;
697 mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
698 mp->m_blockwmask = mp->m_blockwsize - 1;
699
700 mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1);
701 mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0);
702 mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2;
703 mp->m_alloc_mnr[1] = mp->m_alloc_mxr[1] / 2;
704
705 mp->m_inobt_mxr[0] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 1);
706 mp->m_inobt_mxr[1] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 0);
707 mp->m_inobt_mnr[0] = mp->m_inobt_mxr[0] / 2;
708 mp->m_inobt_mnr[1] = mp->m_inobt_mxr[1] / 2;
709
710 mp->m_bmap_dmxr[0] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 1);
711 mp->m_bmap_dmxr[1] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 0);
712 mp->m_bmap_dmnr[0] = mp->m_bmap_dmxr[0] / 2;
713 mp->m_bmap_dmnr[1] = mp->m_bmap_dmxr[1] / 2;
714
715 mp->m_bsize = XFS_FSB_TO_BB(mp, 1);
716 mp->m_ialloc_inos = (int)MAX((__uint16_t)XFS_INODES_PER_CHUNK,
717 sbp->sb_inopblock);
718 mp->m_ialloc_blks = mp->m_ialloc_inos >> sbp->sb_inopblog;
719}
720
721/*
722 * xfs_initialize_perag_data
723 *
724 * Read in each per-ag structure so we can count up the number of
725 * allocated inodes, free inodes and used filesystem blocks as this
726 * information is no longer persistent in the superblock. Once we have
727 * this information, write it into the in-core superblock structure.
728 */
729int
730xfs_initialize_perag_data(
731 struct xfs_mount *mp,
732 xfs_agnumber_t agcount)
733{
734 xfs_agnumber_t index;
735 xfs_perag_t *pag;
736 xfs_sb_t *sbp = &mp->m_sb;
737 uint64_t ifree = 0;
738 uint64_t ialloc = 0;
739 uint64_t bfree = 0;
740 uint64_t bfreelst = 0;
741 uint64_t btree = 0;
742 int error;
743
744 for (index = 0; index < agcount; index++) {
745 /*
746 * read the agf, then the agi. This gets us
747 * all the information we need and populates the
748 * per-ag structures for us.
749 */
750 error = xfs_alloc_pagf_init(mp, NULL, index, 0);
751 if (error)
752 return error;
753
754 error = xfs_ialloc_pagi_init(mp, NULL, index);
755 if (error)
756 return error;
757 pag = xfs_perag_get(mp, index);
758 ifree += pag->pagi_freecount;
759 ialloc += pag->pagi_count;
760 bfree += pag->pagf_freeblks;
761 bfreelst += pag->pagf_flcount;
762 btree += pag->pagf_btreeblks;
763 xfs_perag_put(pag);
764 }
765 /*
766 * Overwrite incore superblock counters with just-read data
767 */
768 spin_lock(&mp->m_sb_lock);
769 sbp->sb_ifree = ifree;
770 sbp->sb_icount = ialloc;
771 sbp->sb_fdblocks = bfree + bfreelst + btree;
772 spin_unlock(&mp->m_sb_lock);
773
774 /* Fixup the per-cpu counters as well. */
775 xfs_icsb_reinit_counters(mp);
776
777 return 0;
778}
779
780/*
781 * xfs_mod_sb() can be used to copy arbitrary changes to the
782 * in-core superblock into the superblock buffer to be logged.
783 * It does not provide the higher level of locking that is
784 * needed to protect the in-core superblock from concurrent
785 * access.
786 */
787void
788xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
789{
790 xfs_buf_t *bp;
791 int first;
792 int last;
793 xfs_mount_t *mp;
794 xfs_sb_field_t f;
795
796 ASSERT(fields);
797 if (!fields)
798 return;
799 mp = tp->t_mountp;
800 bp = xfs_trans_getsb(tp, mp, 0);
801 first = sizeof(xfs_sb_t);
802 last = 0;
803
804 /* translate/copy */
805
806 xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields);
807
808 /* find modified range */
809 f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields);
810 ASSERT((1LL << f) & XFS_SB_MOD_BITS);
811 last = xfs_sb_info[f + 1].offset - 1;
812
813 f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
814 ASSERT((1LL << f) & XFS_SB_MOD_BITS);
815 first = xfs_sb_info[f].offset;
816
817 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF);
818 xfs_trans_log_buf(tp, bp, first, last);
819}