aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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))