diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_alloc.h')
-rw-r--r-- | fs/xfs/libxfs/xfs_alloc.h | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h new file mode 100644 index 000000000000..feacb061bab7 --- /dev/null +++ b/fs/xfs/libxfs/xfs_alloc.h | |||
@@ -0,0 +1,234 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000-2002,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 | #ifndef __XFS_ALLOC_H__ | ||
19 | #define __XFS_ALLOC_H__ | ||
20 | |||
21 | struct xfs_buf; | ||
22 | struct xfs_btree_cur; | ||
23 | struct xfs_mount; | ||
24 | struct xfs_perag; | ||
25 | struct xfs_trans; | ||
26 | |||
27 | extern struct workqueue_struct *xfs_alloc_wq; | ||
28 | |||
29 | /* | ||
30 | * Freespace allocation types. Argument to xfs_alloc_[v]extent. | ||
31 | */ | ||
32 | #define XFS_ALLOCTYPE_ANY_AG 0x01 /* allocate anywhere, use rotor */ | ||
33 | #define XFS_ALLOCTYPE_FIRST_AG 0x02 /* ... start at ag 0 */ | ||
34 | #define XFS_ALLOCTYPE_START_AG 0x04 /* anywhere, start in this a.g. */ | ||
35 | #define XFS_ALLOCTYPE_THIS_AG 0x08 /* anywhere in this a.g. */ | ||
36 | #define XFS_ALLOCTYPE_START_BNO 0x10 /* near this block else anywhere */ | ||
37 | #define XFS_ALLOCTYPE_NEAR_BNO 0x20 /* in this a.g. and near this block */ | ||
38 | #define XFS_ALLOCTYPE_THIS_BNO 0x40 /* at exactly this block */ | ||
39 | |||
40 | /* this should become an enum again when the tracing code is fixed */ | ||
41 | typedef unsigned int xfs_alloctype_t; | ||
42 | |||
43 | #define XFS_ALLOC_TYPES \ | ||
44 | { XFS_ALLOCTYPE_ANY_AG, "ANY_AG" }, \ | ||
45 | { XFS_ALLOCTYPE_FIRST_AG, "FIRST_AG" }, \ | ||
46 | { XFS_ALLOCTYPE_START_AG, "START_AG" }, \ | ||
47 | { XFS_ALLOCTYPE_THIS_AG, "THIS_AG" }, \ | ||
48 | { XFS_ALLOCTYPE_START_BNO, "START_BNO" }, \ | ||
49 | { XFS_ALLOCTYPE_NEAR_BNO, "NEAR_BNO" }, \ | ||
50 | { XFS_ALLOCTYPE_THIS_BNO, "THIS_BNO" } | ||
51 | |||
52 | /* | ||
53 | * Flags for xfs_alloc_fix_freelist. | ||
54 | */ | ||
55 | #define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */ | ||
56 | #define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/ | ||
57 | |||
58 | /* | ||
59 | * In order to avoid ENOSPC-related deadlock caused by | ||
60 | * out-of-order locking of AGF buffer (PV 947395), we place | ||
61 | * constraints on the relationship among actual allocations for | ||
62 | * data blocks, freelist blocks, and potential file data bmap | ||
63 | * btree blocks. However, these restrictions may result in no | ||
64 | * actual space allocated for a delayed extent, for example, a data | ||
65 | * block in a certain AG is allocated but there is no additional | ||
66 | * block for the additional bmap btree block due to a split of the | ||
67 | * bmap btree of the file. The result of this may lead to an | ||
68 | * infinite loop in xfssyncd when the file gets flushed to disk and | ||
69 | * all delayed extents need to be actually allocated. To get around | ||
70 | * this, we explicitly set aside a few blocks which will not be | ||
71 | * reserved in delayed allocation. Considering the minimum number of | ||
72 | * needed freelist blocks is 4 fsbs _per AG_, a potential split of file's bmap | ||
73 | * btree requires 1 fsb, so we set the number of set-aside blocks | ||
74 | * to 4 + 4*agcount. | ||
75 | */ | ||
76 | #define XFS_ALLOC_SET_ASIDE(mp) (4 + ((mp)->m_sb.sb_agcount * 4)) | ||
77 | |||
78 | /* | ||
79 | * When deciding how much space to allocate out of an AG, we limit the | ||
80 | * allocation maximum size to the size the AG. However, we cannot use all the | ||
81 | * blocks in the AG - some are permanently used by metadata. These | ||
82 | * blocks are generally: | ||
83 | * - the AG superblock, AGF, AGI and AGFL | ||
84 | * - the AGF (bno and cnt) and AGI btree root blocks | ||
85 | * - 4 blocks on the AGFL according to XFS_ALLOC_SET_ASIDE() limits | ||
86 | * | ||
87 | * The AG headers are sector sized, so the amount of space they take up is | ||
88 | * dependent on filesystem geometry. The others are all single blocks. | ||
89 | */ | ||
90 | #define XFS_ALLOC_AG_MAX_USABLE(mp) \ | ||
91 | ((mp)->m_sb.sb_agblocks - XFS_BB_TO_FSB(mp, XFS_FSS_TO_BB(mp, 4)) - 7) | ||
92 | |||
93 | |||
94 | /* | ||
95 | * Argument structure for xfs_alloc routines. | ||
96 | * This is turned into a structure to avoid having 20 arguments passed | ||
97 | * down several levels of the stack. | ||
98 | */ | ||
99 | typedef struct xfs_alloc_arg { | ||
100 | struct xfs_trans *tp; /* transaction pointer */ | ||
101 | struct xfs_mount *mp; /* file system mount point */ | ||
102 | struct xfs_buf *agbp; /* buffer for a.g. freelist header */ | ||
103 | struct xfs_perag *pag; /* per-ag struct for this agno */ | ||
104 | xfs_fsblock_t fsbno; /* file system block number */ | ||
105 | xfs_agnumber_t agno; /* allocation group number */ | ||
106 | xfs_agblock_t agbno; /* allocation group-relative block # */ | ||
107 | xfs_extlen_t minlen; /* minimum size of extent */ | ||
108 | xfs_extlen_t maxlen; /* maximum size of extent */ | ||
109 | xfs_extlen_t mod; /* mod value for extent size */ | ||
110 | xfs_extlen_t prod; /* prod value for extent size */ | ||
111 | xfs_extlen_t minleft; /* min blocks must be left after us */ | ||
112 | xfs_extlen_t total; /* total blocks needed in xaction */ | ||
113 | xfs_extlen_t alignment; /* align answer to multiple of this */ | ||
114 | xfs_extlen_t minalignslop; /* slop for minlen+alignment calcs */ | ||
115 | xfs_extlen_t len; /* output: actual size of extent */ | ||
116 | xfs_alloctype_t type; /* allocation type XFS_ALLOCTYPE_... */ | ||
117 | xfs_alloctype_t otype; /* original allocation type */ | ||
118 | char wasdel; /* set if allocation was prev delayed */ | ||
119 | char wasfromfl; /* set if allocation is from freelist */ | ||
120 | char isfl; /* set if is freelist blocks - !acctg */ | ||
121 | char userdata; /* set if this is user data */ | ||
122 | xfs_fsblock_t firstblock; /* io first block allocated */ | ||
123 | } xfs_alloc_arg_t; | ||
124 | |||
125 | /* | ||
126 | * Defines for userdata | ||
127 | */ | ||
128 | #define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/ | ||
129 | #define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */ | ||
130 | |||
131 | /* | ||
132 | * Find the length of the longest extent in an AG. | ||
133 | */ | ||
134 | xfs_extlen_t | ||
135 | xfs_alloc_longest_free_extent(struct xfs_mount *mp, | ||
136 | struct xfs_perag *pag); | ||
137 | |||
138 | /* | ||
139 | * Compute and fill in value of m_ag_maxlevels. | ||
140 | */ | ||
141 | void | ||
142 | xfs_alloc_compute_maxlevels( | ||
143 | struct xfs_mount *mp); /* file system mount structure */ | ||
144 | |||
145 | /* | ||
146 | * Get a block from the freelist. | ||
147 | * Returns with the buffer for the block gotten. | ||
148 | */ | ||
149 | int /* error */ | ||
150 | xfs_alloc_get_freelist( | ||
151 | struct xfs_trans *tp, /* transaction pointer */ | ||
152 | struct xfs_buf *agbp, /* buffer containing the agf structure */ | ||
153 | xfs_agblock_t *bnop, /* block address retrieved from freelist */ | ||
154 | int btreeblk); /* destination is a AGF btree */ | ||
155 | |||
156 | /* | ||
157 | * Log the given fields from the agf structure. | ||
158 | */ | ||
159 | void | ||
160 | xfs_alloc_log_agf( | ||
161 | struct xfs_trans *tp, /* transaction pointer */ | ||
162 | struct xfs_buf *bp, /* buffer for a.g. freelist header */ | ||
163 | int fields);/* mask of fields to be logged (XFS_AGF_...) */ | ||
164 | |||
165 | /* | ||
166 | * Interface for inode allocation to force the pag data to be initialized. | ||
167 | */ | ||
168 | int /* error */ | ||
169 | xfs_alloc_pagf_init( | ||
170 | struct xfs_mount *mp, /* file system mount structure */ | ||
171 | struct xfs_trans *tp, /* transaction pointer */ | ||
172 | xfs_agnumber_t agno, /* allocation group number */ | ||
173 | int flags); /* XFS_ALLOC_FLAGS_... */ | ||
174 | |||
175 | /* | ||
176 | * Put the block on the freelist for the allocation group. | ||
177 | */ | ||
178 | int /* error */ | ||
179 | xfs_alloc_put_freelist( | ||
180 | struct xfs_trans *tp, /* transaction pointer */ | ||
181 | struct xfs_buf *agbp, /* buffer for a.g. freelist header */ | ||
182 | struct xfs_buf *agflbp,/* buffer for a.g. free block array */ | ||
183 | xfs_agblock_t bno, /* block being freed */ | ||
184 | int btreeblk); /* owner was a AGF btree */ | ||
185 | |||
186 | /* | ||
187 | * Read in the allocation group header (free/alloc section). | ||
188 | */ | ||
189 | int /* error */ | ||
190 | xfs_alloc_read_agf( | ||
191 | struct xfs_mount *mp, /* mount point structure */ | ||
192 | struct xfs_trans *tp, /* transaction pointer */ | ||
193 | xfs_agnumber_t agno, /* allocation group number */ | ||
194 | int flags, /* XFS_ALLOC_FLAG_... */ | ||
195 | struct xfs_buf **bpp); /* buffer for the ag freelist header */ | ||
196 | |||
197 | /* | ||
198 | * Allocate an extent (variable-size). | ||
199 | */ | ||
200 | int /* error */ | ||
201 | xfs_alloc_vextent( | ||
202 | xfs_alloc_arg_t *args); /* allocation argument structure */ | ||
203 | |||
204 | /* | ||
205 | * Free an extent. | ||
206 | */ | ||
207 | int /* error */ | ||
208 | xfs_free_extent( | ||
209 | struct xfs_trans *tp, /* transaction pointer */ | ||
210 | xfs_fsblock_t bno, /* starting block number of extent */ | ||
211 | xfs_extlen_t len); /* length of extent */ | ||
212 | |||
213 | int /* error */ | ||
214 | xfs_alloc_lookup_le( | ||
215 | struct xfs_btree_cur *cur, /* btree cursor */ | ||
216 | xfs_agblock_t bno, /* starting block of extent */ | ||
217 | xfs_extlen_t len, /* length of extent */ | ||
218 | int *stat); /* success/failure */ | ||
219 | |||
220 | int /* error */ | ||
221 | xfs_alloc_lookup_ge( | ||
222 | struct xfs_btree_cur *cur, /* btree cursor */ | ||
223 | xfs_agblock_t bno, /* starting block of extent */ | ||
224 | xfs_extlen_t len, /* length of extent */ | ||
225 | int *stat); /* success/failure */ | ||
226 | |||
227 | int /* error */ | ||
228 | xfs_alloc_get_rec( | ||
229 | struct xfs_btree_cur *cur, /* btree cursor */ | ||
230 | xfs_agblock_t *bno, /* output: starting block of extent */ | ||
231 | xfs_extlen_t *len, /* output: length of extent */ | ||
232 | int *stat); /* output: success/failure */ | ||
233 | |||
234 | #endif /* __XFS_ALLOC_H__ */ | ||