aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2018-06-07 10:53:33 -0400
committerDarrick J. Wong <darrick.wong@oracle.com>2018-06-08 13:07:51 -0400
commit86210fbebae6e60b1158ccd6b47ee7ae1abf5b2c (patch)
tree4d705bbf018694eb4ad9c8ba9a19721d8a5e2fdf
parent4a2d01b076d231afebbea04647373644e767b453 (diff)
xfs: move various type verifiers to common file
New verification functions like xfs_verify_fsbno() and xfs_verify_agino() are spread across multiple files and different header files. They really don't fit cleanly into the places they've been put, and have wider scope than the current header includes. Move the type verifiers to a new file in libxfs (xfs-types.c) and the prototypes to xfs_types.h where they will be visible to all the code that uses the types. Signed-Off-By: Dave Chinner <dchinner@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
-rw-r--r--fs/xfs/Makefile1
-rw-r--r--fs/xfs/libxfs/xfs_alloc.c49
-rw-r--r--fs/xfs/libxfs/xfs_alloc.h4
-rw-r--r--fs/xfs/libxfs/xfs_ialloc.c90
-rw-r--r--fs/xfs/libxfs/xfs_ialloc.h7
-rw-r--r--fs/xfs/libxfs/xfs_rtbitmap.c12
-rw-r--r--fs/xfs/libxfs/xfs_types.c173
-rw-r--r--fs/xfs/libxfs/xfs_types.h19
-rw-r--r--fs/xfs/scrub/agheader.c2
9 files changed, 194 insertions, 163 deletions
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 6ccc10b6d77a..2f3f75a7f180 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -50,6 +50,7 @@ xfs-y += $(addprefix libxfs/, \
50 xfs_sb.o \ 50 xfs_sb.o \
51 xfs_symlink_remote.o \ 51 xfs_symlink_remote.o \
52 xfs_trans_resv.o \ 52 xfs_trans_resv.o \
53 xfs_types.o \
53 ) 54 )
54# xfs_rtbitmap is shared with libxfs 55# xfs_rtbitmap is shared with libxfs
55xfs-$(CONFIG_XFS_RT) += $(addprefix libxfs/, \ 56xfs-$(CONFIG_XFS_RT) += $(addprefix libxfs/, \
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index 1db50cfc0212..eef466260d43 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -3123,55 +3123,6 @@ xfs_alloc_query_all(
3123 return xfs_btree_query_all(cur, xfs_alloc_query_range_helper, &query); 3123 return xfs_btree_query_all(cur, xfs_alloc_query_range_helper, &query);
3124} 3124}
3125 3125
3126/* Find the size of the AG, in blocks. */
3127xfs_agblock_t
3128xfs_ag_block_count(
3129 struct xfs_mount *mp,
3130 xfs_agnumber_t agno)
3131{
3132 ASSERT(agno < mp->m_sb.sb_agcount);
3133
3134 if (agno < mp->m_sb.sb_agcount - 1)
3135 return mp->m_sb.sb_agblocks;
3136 return mp->m_sb.sb_dblocks - (agno * mp->m_sb.sb_agblocks);
3137}
3138
3139/*
3140 * Verify that an AG block number pointer neither points outside the AG
3141 * nor points at static metadata.
3142 */
3143bool
3144xfs_verify_agbno(
3145 struct xfs_mount *mp,
3146 xfs_agnumber_t agno,
3147 xfs_agblock_t agbno)
3148{
3149 xfs_agblock_t eoag;
3150
3151 eoag = xfs_ag_block_count(mp, agno);
3152 if (agbno >= eoag)
3153 return false;
3154 if (agbno <= XFS_AGFL_BLOCK(mp))
3155 return false;
3156 return true;
3157}
3158
3159/*
3160 * Verify that an FS block number pointer neither points outside the
3161 * filesystem nor points at static AG metadata.
3162 */
3163bool
3164xfs_verify_fsbno(
3165 struct xfs_mount *mp,
3166 xfs_fsblock_t fsbno)
3167{
3168 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, fsbno);
3169
3170 if (agno >= mp->m_sb.sb_agcount)
3171 return false;
3172 return xfs_verify_agbno(mp, agno, XFS_FSB_TO_AGBNO(mp, fsbno));
3173}
3174
3175/* Is there a record covering a given extent? */ 3126/* Is there a record covering a given extent? */
3176int 3127int
3177xfs_alloc_has_record( 3128xfs_alloc_has_record(
diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h
index 1651d924aaf1..e716c993ac4c 100644
--- a/fs/xfs/libxfs/xfs_alloc.h
+++ b/fs/xfs/libxfs/xfs_alloc.h
@@ -242,10 +242,6 @@ int xfs_alloc_query_range(struct xfs_btree_cur *cur,
242 xfs_alloc_query_range_fn fn, void *priv); 242 xfs_alloc_query_range_fn fn, void *priv);
243int xfs_alloc_query_all(struct xfs_btree_cur *cur, xfs_alloc_query_range_fn fn, 243int xfs_alloc_query_all(struct xfs_btree_cur *cur, xfs_alloc_query_range_fn fn,
244 void *priv); 244 void *priv);
245xfs_agblock_t xfs_ag_block_count(struct xfs_mount *mp, xfs_agnumber_t agno);
246bool xfs_verify_agbno(struct xfs_mount *mp, xfs_agnumber_t agno,
247 xfs_agblock_t agbno);
248bool xfs_verify_fsbno(struct xfs_mount *mp, xfs_fsblock_t fsbno);
249 245
250int xfs_alloc_has_record(struct xfs_btree_cur *cur, xfs_agblock_t bno, 246int xfs_alloc_has_record(struct xfs_btree_cur *cur, xfs_agblock_t bno,
251 xfs_extlen_t len, bool *exist); 247 xfs_extlen_t len, bool *exist);
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
index 3f551eb29157..8ec39dad62d7 100644
--- a/fs/xfs/libxfs/xfs_ialloc.c
+++ b/fs/xfs/libxfs/xfs_ialloc.c
@@ -2674,96 +2674,6 @@ xfs_ialloc_pagi_init(
2674 return 0; 2674 return 0;
2675} 2675}
2676 2676
2677/* Calculate the first and last possible inode number in an AG. */
2678void
2679xfs_ialloc_agino_range(
2680 struct xfs_mount *mp,
2681 xfs_agnumber_t agno,
2682 xfs_agino_t *first,
2683 xfs_agino_t *last)
2684{
2685 xfs_agblock_t bno;
2686 xfs_agblock_t eoag;
2687
2688 eoag = xfs_ag_block_count(mp, agno);
2689
2690 /*
2691 * Calculate the first inode, which will be in the first
2692 * cluster-aligned block after the AGFL.
2693 */
2694 bno = round_up(XFS_AGFL_BLOCK(mp) + 1,
2695 xfs_ialloc_cluster_alignment(mp));
2696 *first = XFS_OFFBNO_TO_AGINO(mp, bno, 0);
2697
2698 /*
2699 * Calculate the last inode, which will be at the end of the
2700 * last (aligned) cluster that can be allocated in the AG.
2701 */
2702 bno = round_down(eoag, xfs_ialloc_cluster_alignment(mp));
2703 *last = XFS_OFFBNO_TO_AGINO(mp, bno, 0) - 1;
2704}
2705
2706/*
2707 * Verify that an AG inode number pointer neither points outside the AG
2708 * nor points at static metadata.
2709 */
2710bool
2711xfs_verify_agino(
2712 struct xfs_mount *mp,
2713 xfs_agnumber_t agno,
2714 xfs_agino_t agino)
2715{
2716 xfs_agino_t first;
2717 xfs_agino_t last;
2718
2719 xfs_ialloc_agino_range(mp, agno, &first, &last);
2720 return agino >= first && agino <= last;
2721}
2722
2723/*
2724 * Verify that an FS inode number pointer neither points outside the
2725 * filesystem nor points at static AG metadata.
2726 */
2727bool
2728xfs_verify_ino(
2729 struct xfs_mount *mp,
2730 xfs_ino_t ino)
2731{
2732 xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, ino);
2733 xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ino);
2734
2735 if (agno >= mp->m_sb.sb_agcount)
2736 return false;
2737 if (XFS_AGINO_TO_INO(mp, agno, agino) != ino)
2738 return false;
2739 return xfs_verify_agino(mp, agno, agino);
2740}
2741
2742/* Is this an internal inode number? */
2743bool
2744xfs_internal_inum(
2745 struct xfs_mount *mp,
2746 xfs_ino_t ino)
2747{
2748 return ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
2749 (xfs_sb_version_hasquota(&mp->m_sb) &&
2750 xfs_is_quota_inode(&mp->m_sb, ino));
2751}
2752
2753/*
2754 * Verify that a directory entry's inode number doesn't point at an internal
2755 * inode, empty space, or static AG metadata.
2756 */
2757bool
2758xfs_verify_dir_ino(
2759 struct xfs_mount *mp,
2760 xfs_ino_t ino)
2761{
2762 if (xfs_internal_inum(mp, ino))
2763 return false;
2764 return xfs_verify_ino(mp, ino);
2765}
2766
2767/* Is there an inode record covering a given range of inode numbers? */ 2677/* Is there an inode record covering a given range of inode numbers? */
2768int 2678int
2769xfs_ialloc_has_inode_record( 2679xfs_ialloc_has_inode_record(
diff --git a/fs/xfs/libxfs/xfs_ialloc.h b/fs/xfs/libxfs/xfs_ialloc.h
index 144f3eac9b93..90b09c5f163b 100644
--- a/fs/xfs/libxfs/xfs_ialloc.h
+++ b/fs/xfs/libxfs/xfs_ialloc.h
@@ -169,12 +169,5 @@ int xfs_inobt_insert_rec(struct xfs_btree_cur *cur, uint16_t holemask,
169 int *stat); 169 int *stat);
170 170
171int xfs_ialloc_cluster_alignment(struct xfs_mount *mp); 171int xfs_ialloc_cluster_alignment(struct xfs_mount *mp);
172void xfs_ialloc_agino_range(struct xfs_mount *mp, xfs_agnumber_t agno,
173 xfs_agino_t *first, xfs_agino_t *last);
174bool xfs_verify_agino(struct xfs_mount *mp, xfs_agnumber_t agno,
175 xfs_agino_t agino);
176bool xfs_verify_ino(struct xfs_mount *mp, xfs_ino_t ino);
177bool xfs_internal_inum(struct xfs_mount *mp, xfs_ino_t ino);
178bool xfs_verify_dir_ino(struct xfs_mount *mp, xfs_ino_t ino);
179 172
180#endif /* __XFS_IALLOC_H__ */ 173#endif /* __XFS_IALLOC_H__ */
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index ffc72075a44e..65fc4ed2e9a1 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -1080,18 +1080,6 @@ xfs_rtalloc_query_all(
1080 return xfs_rtalloc_query_range(tp, &keys[0], &keys[1], fn, priv); 1080 return xfs_rtalloc_query_range(tp, &keys[0], &keys[1], fn, priv);
1081} 1081}
1082 1082
1083/*
1084 * Verify that an realtime block number pointer doesn't point off the
1085 * end of the realtime device.
1086 */
1087bool
1088xfs_verify_rtbno(
1089 struct xfs_mount *mp,
1090 xfs_rtblock_t rtbno)
1091{
1092 return rtbno < mp->m_sb.sb_rblocks;
1093}
1094
1095/* Is the given extent all free? */ 1083/* Is the given extent all free? */
1096int 1084int
1097xfs_rtalloc_extent_is_free( 1085xfs_rtalloc_extent_is_free(
diff --git a/fs/xfs/libxfs/xfs_types.c b/fs/xfs/libxfs/xfs_types.c
new file mode 100644
index 000000000000..2e2a243cef2e
--- /dev/null
+++ b/fs/xfs/libxfs/xfs_types.c
@@ -0,0 +1,173 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
4 * Copyright (C) 2017 Oracle.
5 * All Rights Reserved.
6 */
7#include "xfs.h"
8#include "xfs_fs.h"
9#include "xfs_format.h"
10#include "xfs_log_format.h"
11#include "xfs_shared.h"
12#include "xfs_trans_resv.h"
13#include "xfs_bit.h"
14#include "xfs_sb.h"
15#include "xfs_mount.h"
16#include "xfs_defer.h"
17#include "xfs_inode.h"
18#include "xfs_btree.h"
19#include "xfs_rmap.h"
20#include "xfs_alloc_btree.h"
21#include "xfs_alloc.h"
22#include "xfs_ialloc.h"
23
24/* Find the size of the AG, in blocks. */
25xfs_agblock_t
26xfs_ag_block_count(
27 struct xfs_mount *mp,
28 xfs_agnumber_t agno)
29{
30 ASSERT(agno < mp->m_sb.sb_agcount);
31
32 if (agno < mp->m_sb.sb_agcount - 1)
33 return mp->m_sb.sb_agblocks;
34 return mp->m_sb.sb_dblocks - (agno * mp->m_sb.sb_agblocks);
35}
36
37/*
38 * Verify that an AG block number pointer neither points outside the AG
39 * nor points at static metadata.
40 */
41bool
42xfs_verify_agbno(
43 struct xfs_mount *mp,
44 xfs_agnumber_t agno,
45 xfs_agblock_t agbno)
46{
47 xfs_agblock_t eoag;
48
49 eoag = xfs_ag_block_count(mp, agno);
50 if (agbno >= eoag)
51 return false;
52 if (agbno <= XFS_AGFL_BLOCK(mp))
53 return false;
54 return true;
55}
56
57/*
58 * Verify that an FS block number pointer neither points outside the
59 * filesystem nor points at static AG metadata.
60 */
61bool
62xfs_verify_fsbno(
63 struct xfs_mount *mp,
64 xfs_fsblock_t fsbno)
65{
66 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, fsbno);
67
68 if (agno >= mp->m_sb.sb_agcount)
69 return false;
70 return xfs_verify_agbno(mp, agno, XFS_FSB_TO_AGBNO(mp, fsbno));
71}
72
73/* Calculate the first and last possible inode number in an AG. */
74void
75xfs_agino_range(
76 struct xfs_mount *mp,
77 xfs_agnumber_t agno,
78 xfs_agino_t *first,
79 xfs_agino_t *last)
80{
81 xfs_agblock_t bno;
82 xfs_agblock_t eoag;
83
84 eoag = xfs_ag_block_count(mp, agno);
85
86 /*
87 * Calculate the first inode, which will be in the first
88 * cluster-aligned block after the AGFL.
89 */
90 bno = round_up(XFS_AGFL_BLOCK(mp) + 1,
91 xfs_ialloc_cluster_alignment(mp));
92 *first = XFS_OFFBNO_TO_AGINO(mp, bno, 0);
93
94 /*
95 * Calculate the last inode, which will be at the end of the
96 * last (aligned) cluster that can be allocated in the AG.
97 */
98 bno = round_down(eoag, xfs_ialloc_cluster_alignment(mp));
99 *last = XFS_OFFBNO_TO_AGINO(mp, bno, 0) - 1;
100}
101
102/*
103 * Verify that an AG inode number pointer neither points outside the AG
104 * nor points at static metadata.
105 */
106bool
107xfs_verify_agino(
108 struct xfs_mount *mp,
109 xfs_agnumber_t agno,
110 xfs_agino_t agino)
111{
112 xfs_agino_t first;
113 xfs_agino_t last;
114
115 xfs_agino_range(mp, agno, &first, &last);
116 return agino >= first && agino <= last;
117}
118
119/*
120 * Verify that an FS inode number pointer neither points outside the
121 * filesystem nor points at static AG metadata.
122 */
123bool
124xfs_verify_ino(
125 struct xfs_mount *mp,
126 xfs_ino_t ino)
127{
128 xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, ino);
129 xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ino);
130
131 if (agno >= mp->m_sb.sb_agcount)
132 return false;
133 if (XFS_AGINO_TO_INO(mp, agno, agino) != ino)
134 return false;
135 return xfs_verify_agino(mp, agno, agino);
136}
137
138/* Is this an internal inode number? */
139bool
140xfs_internal_inum(
141 struct xfs_mount *mp,
142 xfs_ino_t ino)
143{
144 return ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
145 (xfs_sb_version_hasquota(&mp->m_sb) &&
146 xfs_is_quota_inode(&mp->m_sb, ino));
147}
148
149/*
150 * Verify that a directory entry's inode number doesn't point at an internal
151 * inode, empty space, or static AG metadata.
152 */
153bool
154xfs_verify_dir_ino(
155 struct xfs_mount *mp,
156 xfs_ino_t ino)
157{
158 if (xfs_internal_inum(mp, ino))
159 return false;
160 return xfs_verify_ino(mp, ino);
161}
162
163/*
164 * Verify that an realtime block number pointer doesn't point off the
165 * end of the realtime device.
166 */
167bool
168xfs_verify_rtbno(
169 struct xfs_mount *mp,
170 xfs_rtblock_t rtbno)
171{
172 return rtbno < mp->m_sb.sb_rblocks;
173}
diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
index b72ae343140e..4055d62f690c 100644
--- a/fs/xfs/libxfs/xfs_types.h
+++ b/fs/xfs/libxfs/xfs_types.h
@@ -147,4 +147,23 @@ typedef struct xfs_bmbt_irec
147 xfs_exntst_t br_state; /* extent state */ 147 xfs_exntst_t br_state; /* extent state */
148} xfs_bmbt_irec_t; 148} xfs_bmbt_irec_t;
149 149
150/*
151 * Type verifier functions
152 */
153struct xfs_mount;
154
155xfs_agblock_t xfs_ag_block_count(struct xfs_mount *mp, xfs_agnumber_t agno);
156bool xfs_verify_agbno(struct xfs_mount *mp, xfs_agnumber_t agno,
157 xfs_agblock_t agbno);
158bool xfs_verify_fsbno(struct xfs_mount *mp, xfs_fsblock_t fsbno);
159
160void xfs_agino_range(struct xfs_mount *mp, xfs_agnumber_t agno,
161 xfs_agino_t *first, xfs_agino_t *last);
162bool xfs_verify_agino(struct xfs_mount *mp, xfs_agnumber_t agno,
163 xfs_agino_t agino);
164bool xfs_verify_ino(struct xfs_mount *mp, xfs_ino_t ino);
165bool xfs_internal_inum(struct xfs_mount *mp, xfs_ino_t ino);
166bool xfs_verify_dir_ino(struct xfs_mount *mp, xfs_ino_t ino);
167bool xfs_verify_rtbno(struct xfs_mount *mp, xfs_rtblock_t rtbno);
168
150#endif /* __XFS_TYPES_H__ */ 169#endif /* __XFS_TYPES_H__ */
diff --git a/fs/xfs/scrub/agheader.c b/fs/xfs/scrub/agheader.c
index fb9637ff4bde..9bb0745f1ad2 100644
--- a/fs/xfs/scrub/agheader.c
+++ b/fs/xfs/scrub/agheader.c
@@ -867,7 +867,7 @@ xfs_scrub_agi(
867 } 867 }
868 868
869 /* Check inode counters */ 869 /* Check inode counters */
870 xfs_ialloc_agino_range(mp, agno, &first_agino, &last_agino); 870 xfs_agino_range(mp, agno, &first_agino, &last_agino);
871 icount = be32_to_cpu(agi->agi_count); 871 icount = be32_to_cpu(agi->agi_count);
872 if (icount > last_agino - first_agino + 1 || 872 if (icount > last_agino - first_agino + 1 ||
873 icount < be32_to_cpu(agi->agi_freecount)) 873 icount < be32_to_cpu(agi->agi_freecount))