Diff markup
1 /* 1 /*
2 * Copyright (c) 2000-2002,2005 Silicon Graphi !! 2 * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
3 * All Rights Reserved. <<
4 * 3 *
5 * This program is free software; you can redi !! 4 * This program is free software; you can redistribute it and/or modify it
6 * modify it under the terms of the GNU Genera !! 5 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
8 * 7 *
9 * This program is distributed in the hope tha !! 8 * This program is distributed in the hope that it would be useful, but
10 * but WITHOUT ANY WARRANTY; without even the !! 9 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR !! 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * GNU General Public License for more details <<
13 * 11 *
14 * You should have received a copy of the GNU !! 12 * Further, this software is distributed without any warranty that it is
15 * along with this program; if not, write the !! 13 * free of the rightful claim of any third person regarding infringement
16 * Inc., 51 Franklin St, Fifth Floor, Boston, !! 14 * or the like. Any license provided herein, whether implied or
>> 15 * otherwise, applies only to this software file. Patent licenses, if
>> 16 * any, provided herein do not apply to combinations of this program with
>> 17 * other software, or any other product whatsoever.
>> 18 *
>> 19 * You should have received a copy of the GNU General Public License along
>> 20 * with this program; if not, write the Free Software Foundation, Inc., 59
>> 21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
>> 22 *
>> 23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
>> 24 * Mountain View, CA 94043, or:
>> 25 *
>> 26 * http://www.sgi.com
>> 27 *
>> 28 * For further information regarding this notice, see:
>> 29 *
>> 30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
17 */ 31 */
>> 32
18 #include "xfs.h" 33 #include "xfs.h"
19 #include "xfs_fs.h" !! 34
>> 35 #include "xfs_macros.h"
20 #include "xfs_types.h" 36 #include "xfs_types.h"
21 #include "xfs_bit.h" <<
22 #include "xfs_log.h" <<
23 #include "xfs_inum.h" 37 #include "xfs_inum.h"
>> 38 #include "xfs_log.h"
24 #include "xfs_trans.h" 39 #include "xfs_trans.h"
25 #include "xfs_sb.h" 40 #include "xfs_sb.h"
26 #include "xfs_ag.h" 41 #include "xfs_ag.h"
>> 42 #include "xfs_dir.h"
27 #include "xfs_dir2.h" 43 #include "xfs_dir2.h"
28 #include "xfs_dmapi.h" 44 #include "xfs_dmapi.h"
29 #include "xfs_mount.h" 45 #include "xfs_mount.h"
30 #include "xfs_bmap_btree.h" <<
31 #include "xfs_alloc_btree.h" 46 #include "xfs_alloc_btree.h"
>> 47 #include "xfs_bmap_btree.h"
32 #include "xfs_ialloc_btree.h" 48 #include "xfs_ialloc_btree.h"
33 #include "xfs_dir2_sf.h" !! 49 #include "xfs_btree.h"
>> 50 #include "xfs_ialloc.h"
34 #include "xfs_attr_sf.h" 51 #include "xfs_attr_sf.h"
>> 52 #include "xfs_dir_sf.h"
>> 53 #include "xfs_dir2_sf.h"
35 #include "xfs_dinode.h" 54 #include "xfs_dinode.h"
36 #include "xfs_inode.h" 55 #include "xfs_inode.h"
37 #include "xfs_btree.h" <<
38 #include "xfs_ialloc.h" <<
39 #include "xfs_alloc.h" 56 #include "xfs_alloc.h"
>> 57 #include "xfs_bit.h"
40 #include "xfs_rtalloc.h" 58 #include "xfs_rtalloc.h"
41 #include "xfs_error.h" 59 #include "xfs_error.h"
42 #include "xfs_bmap.h" 60 #include "xfs_bmap.h"
43 61
44 <<
45 /* <<
46 * Allocation group level functions. <<
47 */ <<
48 static inline int <<
49 xfs_ialloc_cluster_alignment( <<
50 xfs_alloc_arg_t *args) <<
51 { <<
52 if (xfs_sb_version_hasalign(&args->mp- <<
53 args->mp->m_sb.sb_inoalignmt >= <<
54 XFS_B_TO_FSBT(args->mp, XFS_INODE <<
55 return args->mp->m_sb.sb_inoal <<
56 return 1; <<
57 } <<
58 <<
59 /* <<
60 * Lookup the record equal to ino in the btree <<
61 */ <<
62 STATIC int /* err <<
63 xfs_inobt_lookup_eq( <<
64 struct xfs_btree_cur *cur, /* btr <<
65 xfs_agino_t ino, /* sta <<
66 __int32_t fcnt, /* fre <<
67 xfs_inofree_t free, /* fre <<
68 int *stat) /* suc <<
69 { <<
70 cur->bc_rec.i.ir_startino = ino; <<
71 cur->bc_rec.i.ir_freecount = fcnt; <<
72 cur->bc_rec.i.ir_free = free; <<
73 return xfs_btree_lookup(cur, XFS_LOOKU <<
74 } <<
75 <<
76 /* 62 /*
77 * Lookup the first record greater than or equ !! 63 * Log specified fields for the inode given by bp and off.
78 * in the btree given by cur. <<
79 */ 64 */
80 int /* err !! 65 STATIC void
81 xfs_inobt_lookup_ge( !! 66 xfs_ialloc_log_di(
82 struct xfs_btree_cur *cur, /* btr !! 67 xfs_trans_t *tp, /* transaction pointer */
83 xfs_agino_t ino, /* sta !! 68 xfs_buf_t *bp, /* inode buffer */
84 __int32_t fcnt, /* fre !! 69 int off, /* index of inode in buffer */
85 xfs_inofree_t free, /* fre !! 70 int fields) /* bitmask of fields to log */
86 int *stat) /* suc <<
87 { <<
88 cur->bc_rec.i.ir_startino = ino; <<
89 cur->bc_rec.i.ir_freecount = fcnt; <<
90 cur->bc_rec.i.ir_free = free; <<
91 return xfs_btree_lookup(cur, XFS_LOOKU <<
92 } <<
93 <<
94 /* <<
95 * Lookup the first record less than or equal <<
96 * in the btree given by cur. <<
97 */ <<
98 int /* err <<
99 xfs_inobt_lookup_le( <<
100 struct xfs_btree_cur *cur, /* btr <<
101 xfs_agino_t ino, /* sta <<
102 __int32_t fcnt, /* fre <<
103 xfs_inofree_t free, /* fre <<
104 int *stat) /* suc <<
105 { 71 {
106 cur->bc_rec.i.ir_startino = ino; !! 72 int first; /* first byte number */
107 cur->bc_rec.i.ir_freecount = fcnt; !! 73 int ioffset; /* off in bytes */
108 cur->bc_rec.i.ir_free = free; !! 74 int last; /* last byte number */
109 return xfs_btree_lookup(cur, XFS_LOOKU !! 75 xfs_mount_t *mp; /* mount point structure */
110 } !! 76 static const short offsets[] = { /* field offsets */
>> 77 /* keep in sync with bits */
>> 78 offsetof(xfs_dinode_core_t, di_magic),
>> 79 offsetof(xfs_dinode_core_t, di_mode),
>> 80 offsetof(xfs_dinode_core_t, di_version),
>> 81 offsetof(xfs_dinode_core_t, di_format),
>> 82 offsetof(xfs_dinode_core_t, di_onlink),
>> 83 offsetof(xfs_dinode_core_t, di_uid),
>> 84 offsetof(xfs_dinode_core_t, di_gid),
>> 85 offsetof(xfs_dinode_core_t, di_nlink),
>> 86 offsetof(xfs_dinode_core_t, di_projid),
>> 87 offsetof(xfs_dinode_core_t, di_pad),
>> 88 offsetof(xfs_dinode_core_t, di_atime),
>> 89 offsetof(xfs_dinode_core_t, di_mtime),
>> 90 offsetof(xfs_dinode_core_t, di_ctime),
>> 91 offsetof(xfs_dinode_core_t, di_size),
>> 92 offsetof(xfs_dinode_core_t, di_nblocks),
>> 93 offsetof(xfs_dinode_core_t, di_extsize),
>> 94 offsetof(xfs_dinode_core_t, di_nextents),
>> 95 offsetof(xfs_dinode_core_t, di_anextents),
>> 96 offsetof(xfs_dinode_core_t, di_forkoff),
>> 97 offsetof(xfs_dinode_core_t, di_aformat),
>> 98 offsetof(xfs_dinode_core_t, di_dmevmask),
>> 99 offsetof(xfs_dinode_core_t, di_dmstate),
>> 100 offsetof(xfs_dinode_core_t, di_flags),
>> 101 offsetof(xfs_dinode_core_t, di_gen),
>> 102 offsetof(xfs_dinode_t, di_next_unlinked),
>> 103 offsetof(xfs_dinode_t, di_u),
>> 104 offsetof(xfs_dinode_t, di_a),
>> 105 sizeof(xfs_dinode_t)
>> 106 };
111 107
112 /* <<
113 * Update the record referred to by cur to the <<
114 * by [ino, fcnt, free]. <<
115 * This either works (return 0) or gets an EFS <<
116 */ <<
117 STATIC int /* err <<
118 xfs_inobt_update( <<
119 struct xfs_btree_cur *cur, /* btr <<
120 xfs_agino_t ino, /* sta <<
121 __int32_t fcnt, /* fre <<
122 xfs_inofree_t free) /* fre <<
123 { <<
124 union xfs_btree_rec rec; <<
125 108
126 rec.inobt.ir_startino = cpu_to_be32(in !! 109 ASSERT(offsetof(xfs_dinode_t, di_core) == 0);
127 rec.inobt.ir_freecount = cpu_to_be32(f !! 110 ASSERT((fields & (XFS_DI_U|XFS_DI_A)) == 0);
128 rec.inobt.ir_free = cpu_to_be64(free); !! 111 mp = tp->t_mountp;
129 return xfs_btree_update(cur, &rec); !! 112 /*
>> 113 * Get the inode-relative first and last bytes for these fields
>> 114 */
>> 115 xfs_btree_offsets(fields, offsets, XFS_DI_NUM_BITS, &first, &last);
>> 116 /*
>> 117 * Convert to buffer offsets and log it.
>> 118 */
>> 119 ioffset = off << mp->m_sb.sb_inodelog;
>> 120 first += ioffset;
>> 121 last += ioffset;
>> 122 xfs_trans_log_buf(tp, bp, first, last);
130 } 123 }
131 124
132 /* 125 /*
133 * Get the data from the pointed-to record. !! 126 * Allocation group level functions.
134 */ 127 */
135 int /* err <<
136 xfs_inobt_get_rec( <<
137 struct xfs_btree_cur *cur, /* btr <<
138 xfs_agino_t *ino, /* out <<
139 __int32_t *fcnt, /* out <<
140 xfs_inofree_t *free, /* out <<
141 int *stat) /* out <<
142 { <<
143 union xfs_btree_rec *rec; <<
144 int error; <<
145 <<
146 error = xfs_btree_get_rec(cur, &rec, s <<
147 if (!error && *stat == 1) { <<
148 *ino = be32_to_cpu(rec->inobt. <<
149 *fcnt = be32_to_cpu(rec->inobt <<
150 *free = be64_to_cpu(rec->inobt <<
151 } <<
152 return error; <<
153 } <<
154 128
155 /* 129 /*
156 * Allocate new inodes in the allocation group 130 * Allocate new inodes in the allocation group specified by agbp.
157 * Return 0 for success, else error code. 131 * Return 0 for success, else error code.
158 */ 132 */
159 STATIC int /* err 133 STATIC int /* error code or 0 */
160 xfs_ialloc_ag_alloc( 134 xfs_ialloc_ag_alloc(
161 xfs_trans_t *tp, /* tra 135 xfs_trans_t *tp, /* transaction pointer */
162 xfs_buf_t *agbp, /* all 136 xfs_buf_t *agbp, /* alloc group buffer */
163 int *alloc) 137 int *alloc)
164 { 138 {
165 xfs_agi_t *agi; /* all 139 xfs_agi_t *agi; /* allocation group header */
166 xfs_alloc_arg_t args; /* all 140 xfs_alloc_arg_t args; /* allocation argument structure */
167 int blks_per_cluster; /* 141 int blks_per_cluster; /* fs blocks per inode cluster */
168 xfs_btree_cur_t *cur; /* ino 142 xfs_btree_cur_t *cur; /* inode btree cursor */
169 xfs_daddr_t d; /* dis 143 xfs_daddr_t d; /* disk addr of buffer */
170 xfs_agnumber_t agno; <<
171 int error; 144 int error;
172 xfs_buf_t *fbuf; /* new 145 xfs_buf_t *fbuf; /* new free inodes' buffer */
173 xfs_dinode_t *free; /* new 146 xfs_dinode_t *free; /* new free inode structure */
174 int i; /* ino 147 int i; /* inode counter */
175 int j; /* blo 148 int j; /* block counter */
176 int nbufs; /* num 149 int nbufs; /* num bufs of new inodes */
177 xfs_agino_t newino; /* new 150 xfs_agino_t newino; /* new first inode's number */
178 xfs_agino_t newlen; /* new 151 xfs_agino_t newlen; /* new number of inodes */
179 int ninodes; /* num 152 int ninodes; /* num inodes per buf */
180 xfs_agino_t thisino; /* cur 153 xfs_agino_t thisino; /* current inode number, for loop */
181 int version; /* ino 154 int version; /* inode version number to use */
182 int isaligned = 0; /* ino !! 155 int isaligned; /* inode allocation at stripe unit */
183 /* bou 156 /* boundary */
184 unsigned int gen; !! 157 xfs_dinode_core_t dic; /* a dinode_core to copy to new */
>> 158 /* inodes */
185 159
186 args.tp = tp; 160 args.tp = tp;
187 args.mp = tp->t_mountp; 161 args.mp = tp->t_mountp;
188 162
189 /* 163 /*
190 * Locking will ensure that we don't h 164 * Locking will ensure that we don't have two callers in here
191 * at one time. 165 * at one time.
192 */ 166 */
193 newlen = XFS_IALLOC_INODES(args.mp); 167 newlen = XFS_IALLOC_INODES(args.mp);
194 if (args.mp->m_maxicount && 168 if (args.mp->m_maxicount &&
195 args.mp->m_sb.sb_icount + newlen > 169 args.mp->m_sb.sb_icount + newlen > args.mp->m_maxicount)
196 return XFS_ERROR(ENOSPC); 170 return XFS_ERROR(ENOSPC);
197 args.minlen = args.maxlen = XFS_IALLOC 171 args.minlen = args.maxlen = XFS_IALLOC_BLOCKS(args.mp);
198 /* 172 /*
199 * First try to allocate inodes contig !! 173 * Set the alignment for the allocation.
200 * chunk of inodes. If the filesystem !! 174 * If stripe alignment is turned on then align at stripe unit
201 * an entire stripe unit with inodes. !! 175 * boundary.
202 */ !! 176 * If the cluster size is smaller than a filesystem block
203 agi = XFS_BUF_TO_AGI(agbp); !! 177 * then we're doing I/O for inodes in filesystem block size pieces,
204 newino = be32_to_cpu(agi->agi_newino); !! 178 * so don't need alignment anyway.
205 args.agbno = XFS_AGINO_TO_AGBNO(args.m !! 179 */
206 XFS_IALLOC_BLOCKS(args !! 180 isaligned = 0;
207 if (likely(newino != NULLAGINO && !! 181 if (args.mp->m_sinoalign) {
208 (args.agbno < be32_to_cpu(ag !! 182 ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN));
209 args.fsbno = XFS_AGB_TO_FSB(ar !! 183 args.alignment = args.mp->m_dalign;
210 be32_to_cpu(ag !! 184 isaligned = 1;
211 args.type = XFS_ALLOCTYPE_THIS !! 185 } else if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) &&
212 args.mod = args.total = args.w !! 186 args.mp->m_sb.sb_inoalignmt >=
213 args.userdata = args.m !! 187 XFS_B_TO_FSBT(args.mp, XFS_INODE_CLUSTER_SIZE(args.mp)))
214 args.prod = 1; !! 188 args.alignment = args.mp->m_sb.sb_inoalignmt;
215 !! 189 else
216 /* <<
217 * We need to take into accoun <<
218 * we don't modify the free li <<
219 * block. If we don't have an <<
220 * attempt allocation attempt <<
221 * a dirty transaction and shu <<
222 * <<
223 * For an exact allocation, al <<
224 * however we need to take clu <<
225 * fixing up the freelist. Use <<
226 * indicate that extra blocks <<
227 * but not to use them in the <<
228 */ <<
229 args.alignment = 1; 190 args.alignment = 1;
230 args.minalignslop = xfs_ialloc !! 191 agi = XFS_BUF_TO_AGI(agbp);
231 !! 192 /*
232 /* Allow space for the inode b !! 193 * Need to figure out where to allocate the inode blocks.
233 args.minleft = args.mp->m_in_m !! 194 * Ideally they should be spaced out through the a.g.
234 if ((error = xfs_alloc_vextent !! 195 * For now, just allocate blocks up front.
235 return error; !! 196 */
236 } else !! 197 args.agbno = INT_GET(agi->agi_root, ARCH_CONVERT);
237 args.fsbno = NULLFSBLOCK; !! 198 args.fsbno = XFS_AGB_TO_FSB(args.mp, INT_GET(agi->agi_seqno, ARCH_CONVERT),
238 !! 199 args.agbno);
239 if (unlikely(args.fsbno == NULLFSBLOCK !! 200 /*
240 /* !! 201 * Allocate a fixed-size extent of inodes.
241 * Set the alignment for the a !! 202 */
242 * If stripe alignment is turn !! 203 args.type = XFS_ALLOCTYPE_NEAR_BNO;
243 * boundary. !! 204 args.mod = args.total = args.wasdel = args.isfl = args.userdata =
244 * If the cluster size is smal !! 205 args.minalignslop = 0;
245 * then we're doing I/O for in !! 206 args.prod = 1;
246 * pieces, so don't need align !! 207 /*
247 */ !! 208 * Allow space for the inode btree to split.
248 isaligned = 0; !! 209 */
249 if (args.mp->m_sinoalign) { !! 210 args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1;
250 ASSERT(!(args.mp->m_fl !! 211 if ((error = xfs_alloc_vextent(&args)))
251 args.alignment = args. !! 212 return error;
252 isaligned = 1; <<
253 } else <<
254 args.alignment = xfs_i <<
255 /* <<
256 * Need to figure out where to <<
257 * Ideally they should be spac <<
258 * For now, just allocate bloc <<
259 */ <<
260 args.agbno = be32_to_cpu(agi-> <<
261 args.fsbno = XFS_AGB_TO_FSB(ar <<
262 be32_to_cpu(ag <<
263 /* <<
264 * Allocate a fixed-size exten <<
265 */ <<
266 args.type = XFS_ALLOCTYPE_NEAR <<
267 args.mod = args.total = args.w <<
268 args.userdata = args.m <<
269 args.prod = 1; <<
270 /* <<
271 * Allow space for the inode b <<
272 */ <<
273 args.minleft = args.mp->m_in_m <<
274 if ((error = xfs_alloc_vextent <<
275 return error; <<
276 } <<
277 213
278 /* 214 /*
279 * If stripe alignment is turned on, t 215 * If stripe alignment is turned on, then try again with cluster
280 * alignment. 216 * alignment.
281 */ 217 */
282 if (isaligned && args.fsbno == NULLFSB 218 if (isaligned && args.fsbno == NULLFSBLOCK) {
283 args.type = XFS_ALLOCTYPE_NEAR 219 args.type = XFS_ALLOCTYPE_NEAR_BNO;
284 args.agbno = be32_to_cpu(agi-> !! 220 args.agbno = INT_GET(agi->agi_root, ARCH_CONVERT);
285 args.fsbno = XFS_AGB_TO_FSB(ar 221 args.fsbno = XFS_AGB_TO_FSB(args.mp,
286 be32_to_cpu(ag !! 222 INT_GET(agi->agi_seqno, ARCH_CONVERT), args.agbno);
287 args.alignment = xfs_ialloc_cl !! 223 if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) &&
>> 224 args.mp->m_sb.sb_inoalignmt >=
>> 225 XFS_B_TO_FSBT(args.mp, XFS_INODE_CLUSTER_SIZE(args.mp)))
>> 226 args.alignment = args.mp->m_sb.sb_inoalignmt;
>> 227 else
>> 228 args.alignment = 1;
288 if ((error = xfs_alloc_vextent 229 if ((error = xfs_alloc_vextent(&args)))
289 return error; 230 return error;
290 } 231 }
291 232
292 if (args.fsbno == NULLFSBLOCK) { 233 if (args.fsbno == NULLFSBLOCK) {
293 *alloc = 0; 234 *alloc = 0;
294 return 0; 235 return 0;
295 } 236 }
296 ASSERT(args.len == args.minlen); 237 ASSERT(args.len == args.minlen);
297 /* 238 /*
298 * Convert the results. 239 * Convert the results.
299 */ 240 */
300 newino = XFS_OFFBNO_TO_AGINO(args.mp, 241 newino = XFS_OFFBNO_TO_AGINO(args.mp, args.agbno, 0);
301 /* 242 /*
302 * Loop over the new block(s), filling 243 * Loop over the new block(s), filling in the inodes.
303 * For small block sizes, manipulate t 244 * For small block sizes, manipulate the inodes in buffers
304 * which are multiples of the blocks s 245 * which are multiples of the blocks size.
305 */ 246 */
306 if (args.mp->m_sb.sb_blocksize >= XFS_ 247 if (args.mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(args.mp)) {
307 blks_per_cluster = 1; 248 blks_per_cluster = 1;
308 nbufs = (int)args.len; 249 nbufs = (int)args.len;
309 ninodes = args.mp->m_sb.sb_ino 250 ninodes = args.mp->m_sb.sb_inopblock;
310 } else { 251 } else {
311 blks_per_cluster = XFS_INODE_C 252 blks_per_cluster = XFS_INODE_CLUSTER_SIZE(args.mp) /
312 args.mp->m_ 253 args.mp->m_sb.sb_blocksize;
313 nbufs = (int)args.len / blks_p 254 nbufs = (int)args.len / blks_per_cluster;
314 ninodes = blks_per_cluster * a 255 ninodes = blks_per_cluster * args.mp->m_sb.sb_inopblock;
315 } 256 }
316 /* 257 /*
317 * Figure out what version number to u 258 * Figure out what version number to use in the inodes we create.
318 * If the superblock version has caugh 259 * If the superblock version has caught up to the one that supports
319 * the new inode format, then use the 260 * the new inode format, then use the new inode version. Otherwise
320 * use the old version so that old ker 261 * use the old version so that old kernels will continue to be
321 * able to use the file system. 262 * able to use the file system.
322 */ 263 */
323 if (xfs_sb_version_hasnlink(&args.mp-> !! 264 if (XFS_SB_VERSION_HASNLINK(&args.mp->m_sb))
324 version = 2; !! 265 version = XFS_DINODE_VERSION_2;
325 else 266 else
326 version = 1; !! 267 version = XFS_DINODE_VERSION_1;
>> 268
>> 269 memset(&dic, 0, sizeof(xfs_dinode_core_t));
>> 270 INT_SET(dic.di_magic, ARCH_CONVERT, XFS_DINODE_MAGIC);
>> 271 INT_SET(dic.di_version, ARCH_CONVERT, version);
327 272
328 /* <<
329 * Seed the new inode cluster with a r <<
330 * prevents short-term reuse of genera <<
331 * freed and then immediately realloca <<
332 * rather than a linear progression to <<
333 * number from being easily guessable. <<
334 */ <<
335 gen = random32(); <<
336 for (j = 0; j < nbufs; j++) { 273 for (j = 0; j < nbufs; j++) {
337 /* 274 /*
338 * Get the block. 275 * Get the block.
339 */ 276 */
340 d = XFS_AGB_TO_DADDR(args.mp, !! 277 d = XFS_AGB_TO_DADDR(args.mp, INT_GET(agi->agi_seqno, ARCH_CONVERT),
341 args.agbn 278 args.agbno + (j * blks_per_cluster));
342 fbuf = xfs_trans_get_buf(tp, a 279 fbuf = xfs_trans_get_buf(tp, args.mp->m_ddev_targp, d,
343 args. 280 args.mp->m_bsize * blks_per_cluster,
344 XFS_B 281 XFS_BUF_LOCK);
345 ASSERT(fbuf); 282 ASSERT(fbuf);
346 ASSERT(!XFS_BUF_GETERROR(fbuf) 283 ASSERT(!XFS_BUF_GETERROR(fbuf));
347 <<
348 /* 284 /*
349 * Initialize all inodes in th !! 285 * Loop over the inodes in this buffer.
350 * <<
351 * XXX: It would be much bette <<
352 * log a whole cluster of <<
353 * transactions causing a <<
354 */ 286 */
355 xfs_biozero(fbuf, 0, ninodes < <<
356 for (i = 0; i < ninodes; i++) <<
357 int ioffset = i << <<
358 uint isize = sizeof <<
359 287
360 free = xfs_make_iptr(a !! 288 for (i = 0; i < ninodes; i++) {
361 free->di_magic = cpu_t !! 289 free = XFS_MAKE_IPTR(args.mp, fbuf, i);
362 free->di_version = ver !! 290 memcpy(&(free->di_core), &dic, sizeof(xfs_dinode_core_t));
363 free->di_gen = cpu_to_ !! 291 INT_SET(free->di_next_unlinked, ARCH_CONVERT, NULLAGINO);
364 free->di_next_unlinked !! 292 xfs_ialloc_log_di(tp, fbuf, i,
365 xfs_trans_log_buf(tp, !! 293 XFS_DI_CORE_BITS | XFS_DI_NEXT_UNLINKED);
366 } 294 }
367 xfs_trans_inode_alloc_buf(tp, 295 xfs_trans_inode_alloc_buf(tp, fbuf);
368 } 296 }
369 be32_add_cpu(&agi->agi_count, newlen); !! 297 INT_MOD(agi->agi_count, ARCH_CONVERT, newlen);
370 be32_add_cpu(&agi->agi_freecount, newl !! 298 INT_MOD(agi->agi_freecount, ARCH_CONVERT, newlen);
371 agno = be32_to_cpu(agi->agi_seqno); <<
372 down_read(&args.mp->m_peraglock); 299 down_read(&args.mp->m_peraglock);
373 args.mp->m_perag[agno].pagi_freecount !! 300 args.mp->m_perag[INT_GET(agi->agi_seqno, ARCH_CONVERT)].pagi_freecount += newlen;
374 up_read(&args.mp->m_peraglock); 301 up_read(&args.mp->m_peraglock);
375 agi->agi_newino = cpu_to_be32(newino); !! 302 INT_SET(agi->agi_newino, ARCH_CONVERT, newino);
376 /* 303 /*
377 * Insert records describing the new i 304 * Insert records describing the new inode chunk into the btree.
378 */ 305 */
379 cur = xfs_inobt_init_cursor(args.mp, t !! 306 cur = xfs_btree_init_cursor(args.mp, tp, agbp,
>> 307 INT_GET(agi->agi_seqno, ARCH_CONVERT),
>> 308 XFS_BTNUM_INO, (xfs_inode_t *)0, 0);
380 for (thisino = newino; 309 for (thisino = newino;
381 thisino < newino + newlen; 310 thisino < newino + newlen;
382 thisino += XFS_INODES_PER_CHUNK) 311 thisino += XFS_INODES_PER_CHUNK) {
383 if ((error = xfs_inobt_lookup_ 312 if ((error = xfs_inobt_lookup_eq(cur, thisino,
384 XFS_INODES_PER 313 XFS_INODES_PER_CHUNK, XFS_INOBT_ALL_FREE, &i))) {
385 xfs_btree_del_cursor(c 314 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
386 return error; 315 return error;
387 } 316 }
388 ASSERT(i == 0); 317 ASSERT(i == 0);
389 if ((error = xfs_btree_insert( !! 318 if ((error = xfs_inobt_insert(cur, &i))) {
390 xfs_btree_del_cursor(c 319 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
391 return error; 320 return error;
392 } 321 }
393 ASSERT(i == 1); 322 ASSERT(i == 1);
394 } 323 }
395 xfs_btree_del_cursor(cur, XFS_BTREE_NO 324 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
396 /* 325 /*
397 * Log allocation group header fields 326 * Log allocation group header fields
398 */ 327 */
399 xfs_ialloc_log_agi(tp, agbp, 328 xfs_ialloc_log_agi(tp, agbp,
400 XFS_AGI_COUNT | XFS_AGI_FREECO 329 XFS_AGI_COUNT | XFS_AGI_FREECOUNT | XFS_AGI_NEWINO);
401 /* 330 /*
402 * Modify/log superblock values for in 331 * Modify/log superblock values for inode count and inode free count.
403 */ 332 */
404 xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOU 333 xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, (long)newlen);
405 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFRE 334 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, (long)newlen);
406 *alloc = 1; 335 *alloc = 1;
407 return 0; 336 return 0;
408 } 337 }
409 338
410 STATIC_INLINE xfs_agnumber_t !! 339 STATIC __inline xfs_agnumber_t
411 xfs_ialloc_next_ag( 340 xfs_ialloc_next_ag(
412 xfs_mount_t *mp) 341 xfs_mount_t *mp)
413 { 342 {
414 xfs_agnumber_t agno; 343 xfs_agnumber_t agno;
415 344
416 spin_lock(&mp->m_agirotor_lock); 345 spin_lock(&mp->m_agirotor_lock);
417 agno = mp->m_agirotor; 346 agno = mp->m_agirotor;
418 if (++mp->m_agirotor == mp->m_maxagi) 347 if (++mp->m_agirotor == mp->m_maxagi)
419 mp->m_agirotor = 0; 348 mp->m_agirotor = 0;
420 spin_unlock(&mp->m_agirotor_lock); 349 spin_unlock(&mp->m_agirotor_lock);
421 350
422 return agno; 351 return agno;
423 } 352 }
424 353
425 /* 354 /*
426 * Select an allocation group to look for a fr 355 * Select an allocation group to look for a free inode in, based on the parent
427 * inode and then mode. Return the allocation 356 * inode and then mode. Return the allocation group buffer.
428 */ 357 */
429 STATIC xfs_buf_t * /* all 358 STATIC xfs_buf_t * /* allocation group buffer */
430 xfs_ialloc_ag_select( 359 xfs_ialloc_ag_select(
431 xfs_trans_t *tp, /* tra 360 xfs_trans_t *tp, /* transaction pointer */
432 xfs_ino_t parent, /* par 361 xfs_ino_t parent, /* parent directory inode number */
433 mode_t mode, /* bit 362 mode_t mode, /* bits set to indicate file type */
434 int okalloc) /* ok 363 int okalloc) /* ok to allocate more space */
435 { 364 {
436 xfs_buf_t *agbp; /* all 365 xfs_buf_t *agbp; /* allocation group header buffer */
437 xfs_agnumber_t agcount; /* num 366 xfs_agnumber_t agcount; /* number of ag's in the filesystem */
438 xfs_agnumber_t agno; /* cur 367 xfs_agnumber_t agno; /* current ag number */
439 int flags; /* all 368 int flags; /* alloc buffer locking flags */
440 xfs_extlen_t ineed; /* blo 369 xfs_extlen_t ineed; /* blocks needed for inode allocation */
441 xfs_extlen_t longest = 0; /* lon 370 xfs_extlen_t longest = 0; /* longest extent available */
442 xfs_mount_t *mp; /* mou 371 xfs_mount_t *mp; /* mount point structure */
443 int needspace; /* fil 372 int needspace; /* file mode implies space allocated */
444 xfs_perag_t *pag; /* per 373 xfs_perag_t *pag; /* per allocation group data */
445 xfs_agnumber_t pagno; /* par 374 xfs_agnumber_t pagno; /* parent (starting) ag number */
446 375
447 /* 376 /*
448 * Files of these types need at least 377 * Files of these types need at least one block if length > 0
449 * (and they won't fit in the inode, b 378 * (and they won't fit in the inode, but that's hard to figure out).
450 */ 379 */
451 needspace = S_ISDIR(mode) || S_ISREG(m 380 needspace = S_ISDIR(mode) || S_ISREG(mode) || S_ISLNK(mode);
452 mp = tp->t_mountp; 381 mp = tp->t_mountp;
453 agcount = mp->m_maxagi; 382 agcount = mp->m_maxagi;
454 if (S_ISDIR(mode)) 383 if (S_ISDIR(mode))
455 pagno = xfs_ialloc_next_ag(mp) 384 pagno = xfs_ialloc_next_ag(mp);
456 else { 385 else {
457 pagno = XFS_INO_TO_AGNO(mp, pa 386 pagno = XFS_INO_TO_AGNO(mp, parent);
458 if (pagno >= agcount) 387 if (pagno >= agcount)
459 pagno = 0; 388 pagno = 0;
460 } 389 }
461 ASSERT(pagno < agcount); 390 ASSERT(pagno < agcount);
462 /* 391 /*
463 * Loop through allocation groups, loo 392 * Loop through allocation groups, looking for one with a little
464 * free space in it. Note we don't lo 393 * free space in it. Note we don't look for free inodes, exactly.
465 * Instead, we include whether there i 394 * Instead, we include whether there is a need to allocate inodes
466 * to mean that blocks must be allocat 395 * to mean that blocks must be allocated for them,
467 * if none are currently free. 396 * if none are currently free.
468 */ 397 */
469 agno = pagno; 398 agno = pagno;
470 flags = XFS_ALLOC_FLAG_TRYLOCK; 399 flags = XFS_ALLOC_FLAG_TRYLOCK;
471 down_read(&mp->m_peraglock); 400 down_read(&mp->m_peraglock);
472 for (;;) { 401 for (;;) {
473 pag = &mp->m_perag[agno]; 402 pag = &mp->m_perag[agno];
474 if (!pag->pagi_init) { 403 if (!pag->pagi_init) {
475 if (xfs_ialloc_read_ag 404 if (xfs_ialloc_read_agi(mp, tp, agno, &agbp)) {
476 agbp = NULL; 405 agbp = NULL;
477 goto nextag; 406 goto nextag;
478 } 407 }
479 } else 408 } else
480 agbp = NULL; 409 agbp = NULL;
481 410
482 if (!pag->pagi_inodeok) { 411 if (!pag->pagi_inodeok) {
483 xfs_ialloc_next_ag(mp) 412 xfs_ialloc_next_ag(mp);
484 goto unlock_nextag; 413 goto unlock_nextag;
485 } 414 }
486 415
487 /* 416 /*
488 * Is there enough free space 417 * Is there enough free space for the file plus a block
489 * of inodes (if we need to al 418 * of inodes (if we need to allocate some)?
490 */ 419 */
491 ineed = pag->pagi_freecount ? 420 ineed = pag->pagi_freecount ? 0 : XFS_IALLOC_BLOCKS(mp);
492 if (ineed && !pag->pagf_init) 421 if (ineed && !pag->pagf_init) {
493 if (agbp == NULL && 422 if (agbp == NULL &&
494 xfs_ialloc_read_ag 423 xfs_ialloc_read_agi(mp, tp, agno, &agbp)) {
495 agbp = NULL; 424 agbp = NULL;
496 goto nextag; 425 goto nextag;
497 } 426 }
498 (void)xfs_alloc_pagf_i 427 (void)xfs_alloc_pagf_init(mp, tp, agno, flags);
499 } 428 }
500 if (!ineed || pag->pagf_init) 429 if (!ineed || pag->pagf_init) {
501 if (ineed && !(longest 430 if (ineed && !(longest = pag->pagf_longest))
502 longest = pag- 431 longest = pag->pagf_flcount > 0;
503 if (!ineed || 432 if (!ineed ||
504 (pag->pagf_freeblk 433 (pag->pagf_freeblks >= needspace + ineed &&
505 longest >= ineed 434 longest >= ineed &&
506 okalloc)) { 435 okalloc)) {
507 if (agbp == NU 436 if (agbp == NULL &&
508 xfs_ialloc 437 xfs_ialloc_read_agi(mp, tp, agno, &agbp)) {
509 agbp = 438 agbp = NULL;
510 goto n 439 goto nextag;
511 } 440 }
512 up_read(&mp->m 441 up_read(&mp->m_peraglock);
513 return agbp; 442 return agbp;
514 } 443 }
515 } 444 }
516 unlock_nextag: 445 unlock_nextag:
517 if (agbp) 446 if (agbp)
518 xfs_trans_brelse(tp, a 447 xfs_trans_brelse(tp, agbp);
519 nextag: 448 nextag:
520 /* 449 /*
521 * No point in iterating over 450 * No point in iterating over the rest, if we're shutting
522 * down. 451 * down.
523 */ 452 */
524 if (XFS_FORCED_SHUTDOWN(mp)) { 453 if (XFS_FORCED_SHUTDOWN(mp)) {
525 up_read(&mp->m_peraglo 454 up_read(&mp->m_peraglock);
526 return NULL; !! 455 return (xfs_buf_t *)0;
527 } 456 }
528 agno++; 457 agno++;
529 if (agno >= agcount) 458 if (agno >= agcount)
530 agno = 0; 459 agno = 0;
531 if (agno == pagno) { 460 if (agno == pagno) {
532 if (flags == 0) { 461 if (flags == 0) {
533 up_read(&mp->m 462 up_read(&mp->m_peraglock);
534 return NULL; !! 463 return (xfs_buf_t *)0;
535 } 464 }
536 flags = 0; 465 flags = 0;
537 } 466 }
538 } 467 }
539 } 468 }
540 469
541 /* 470 /*
542 * Visible inode allocation functions. 471 * Visible inode allocation functions.
543 */ 472 */
544 473
545 /* 474 /*
546 * Allocate an inode on disk. 475 * Allocate an inode on disk.
547 * Mode is used to tell whether the new inode 476 * Mode is used to tell whether the new inode will need space, and whether
548 * it is a directory. 477 * it is a directory.
549 * 478 *
550 * The arguments IO_agbp and alloc_done are de 479 * The arguments IO_agbp and alloc_done are defined to work within
551 * the constraint of one allocation per transa 480 * the constraint of one allocation per transaction.
552 * xfs_dialloc() is designed to be called twic 481 * xfs_dialloc() is designed to be called twice if it has to do an
553 * allocation to make more free inodes. On th 482 * allocation to make more free inodes. On the first call,
554 * IO_agbp should be set to NULL. If an inode 483 * IO_agbp should be set to NULL. If an inode is available,
555 * i.e., xfs_dialloc() did not need to do an a 484 * i.e., xfs_dialloc() did not need to do an allocation, an inode
556 * number is returned. In this case, IO_agbp 485 * number is returned. In this case, IO_agbp would be set to the
557 * current ag_buf and alloc_done set to false. 486 * current ag_buf and alloc_done set to false.
558 * If an allocation needed to be done, xfs_dia 487 * If an allocation needed to be done, xfs_dialloc would return
559 * the current ag_buf in IO_agbp and set alloc 488 * the current ag_buf in IO_agbp and set alloc_done to true.
560 * The caller should then commit the current t 489 * The caller should then commit the current transaction, allocate a new
561 * transaction, and call xfs_dialloc() again, 490 * transaction, and call xfs_dialloc() again, passing in the previous
562 * value of IO_agbp. IO_agbp should be held a 491 * value of IO_agbp. IO_agbp should be held across the transactions.
563 * Since the agbp is locked across the two cal 492 * Since the agbp is locked across the two calls, the second call is
564 * guaranteed to have a free inode available. 493 * guaranteed to have a free inode available.
565 * 494 *
566 * Once we successfully pick an inode its numb 495 * Once we successfully pick an inode its number is returned and the
567 * on-disk data structures are updated. The i 496 * on-disk data structures are updated. The inode itself is not read
568 * in, since doing so would break ordering con 497 * in, since doing so would break ordering constraints with xfs_reclaim.
569 */ 498 */
570 int 499 int
571 xfs_dialloc( 500 xfs_dialloc(
572 xfs_trans_t *tp, /* tra 501 xfs_trans_t *tp, /* transaction pointer */
573 xfs_ino_t parent, /* par 502 xfs_ino_t parent, /* parent inode (directory) */
574 mode_t mode, /* mod 503 mode_t mode, /* mode bits for new inode */
575 int okalloc, /* ok 504 int okalloc, /* ok to allocate more space */
576 xfs_buf_t **IO_agbp, /* in/ 505 xfs_buf_t **IO_agbp, /* in/out ag header's buffer */
577 boolean_t *alloc_done, /* tru 506 boolean_t *alloc_done, /* true if we needed to replenish
578 ino 507 inode freelist */
579 xfs_ino_t *inop) /* ino 508 xfs_ino_t *inop) /* inode number allocated */
580 { 509 {
581 xfs_agnumber_t agcount; /* num 510 xfs_agnumber_t agcount; /* number of allocation groups */
582 xfs_buf_t *agbp; /* all 511 xfs_buf_t *agbp; /* allocation group header's buffer */
583 xfs_agnumber_t agno; /* all 512 xfs_agnumber_t agno; /* allocation group number */
584 xfs_agi_t *agi; /* all 513 xfs_agi_t *agi; /* allocation group header structure */
585 xfs_btree_cur_t *cur; /* ino 514 xfs_btree_cur_t *cur; /* inode allocation btree cursor */
586 int error; /* err 515 int error; /* error return value */
587 int i; /* res 516 int i; /* result code */
588 int ialloced; /* ino 517 int ialloced; /* inode allocation status */
589 int noroom = 0; /* no 518 int noroom = 0; /* no space for inode blk allocation */
590 xfs_ino_t ino; /* fs- 519 xfs_ino_t ino; /* fs-relative inode to be returned */
591 /* REFERENCED */ 520 /* REFERENCED */
592 int j; /* res 521 int j; /* result code */
593 xfs_mount_t *mp; /* fil 522 xfs_mount_t *mp; /* file system mount structure */
594 int offset; /* ind 523 int offset; /* index of inode in chunk */
595 xfs_agino_t pagino; /* par 524 xfs_agino_t pagino; /* parent's a.g. relative inode # */
596 xfs_agnumber_t pagno; /* par 525 xfs_agnumber_t pagno; /* parent's allocation group number */
597 xfs_inobt_rec_incore_t rec; /* ino !! 526 xfs_inobt_rec_t rec; /* inode allocation record */
598 xfs_agnumber_t tagno; /* tes 527 xfs_agnumber_t tagno; /* testing allocation group number */
599 xfs_btree_cur_t *tcur; /* tem 528 xfs_btree_cur_t *tcur; /* temp cursor */
600 xfs_inobt_rec_incore_t trec; /* tem !! 529 xfs_inobt_rec_t trec; /* temp inode allocation record */
601 530
602 531
603 if (*IO_agbp == NULL) { 532 if (*IO_agbp == NULL) {
604 /* 533 /*
605 * We do not have an agbp, so 534 * We do not have an agbp, so select an initial allocation
606 * group for inode allocation. 535 * group for inode allocation.
607 */ 536 */
608 agbp = xfs_ialloc_ag_select(tp 537 agbp = xfs_ialloc_ag_select(tp, parent, mode, okalloc);
609 /* 538 /*
610 * Couldn't find an allocation 539 * Couldn't find an allocation group satisfying the
611 * criteria, give up. 540 * criteria, give up.
612 */ 541 */
613 if (!agbp) { 542 if (!agbp) {
614 *inop = NULLFSINO; 543 *inop = NULLFSINO;
615 return 0; 544 return 0;
616 } 545 }
617 agi = XFS_BUF_TO_AGI(agbp); 546 agi = XFS_BUF_TO_AGI(agbp);
618 ASSERT(be32_to_cpu(agi->agi_ma !! 547 ASSERT(INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC);
619 } else { 548 } else {
620 /* 549 /*
621 * Continue where we left off 550 * Continue where we left off before. In this case, we
622 * know that the allocation gr 551 * know that the allocation group has free inodes.
623 */ 552 */
624 agbp = *IO_agbp; 553 agbp = *IO_agbp;
625 agi = XFS_BUF_TO_AGI(agbp); 554 agi = XFS_BUF_TO_AGI(agbp);
626 ASSERT(be32_to_cpu(agi->agi_ma !! 555 ASSERT(INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC);
627 ASSERT(be32_to_cpu(agi->agi_fr !! 556 ASSERT(INT_GET(agi->agi_freecount, ARCH_CONVERT) > 0);
628 } 557 }
629 mp = tp->t_mountp; 558 mp = tp->t_mountp;
630 agcount = mp->m_sb.sb_agcount; 559 agcount = mp->m_sb.sb_agcount;
631 agno = be32_to_cpu(agi->agi_seqno); !! 560 agno = INT_GET(agi->agi_seqno, ARCH_CONVERT);
632 tagno = agno; 561 tagno = agno;
633 pagno = XFS_INO_TO_AGNO(mp, parent); 562 pagno = XFS_INO_TO_AGNO(mp, parent);
634 pagino = XFS_INO_TO_AGINO(mp, parent); 563 pagino = XFS_INO_TO_AGINO(mp, parent);
635 564
636 /* 565 /*
637 * If we have already hit the ceiling 566 * If we have already hit the ceiling of inode blocks then clear
638 * okalloc so we scan all available ag 567 * okalloc so we scan all available agi structures for a free
639 * inode. 568 * inode.
640 */ 569 */
641 570
642 if (mp->m_maxicount && 571 if (mp->m_maxicount &&
643 mp->m_sb.sb_icount + XFS_IALLOC_IN 572 mp->m_sb.sb_icount + XFS_IALLOC_INODES(mp) > mp->m_maxicount) {
644 noroom = 1; 573 noroom = 1;
645 okalloc = 0; 574 okalloc = 0;
646 } 575 }
647 576
648 /* 577 /*
649 * Loop until we find an allocation gr 578 * Loop until we find an allocation group that either has free inodes
650 * or in which we can allocate some in 579 * or in which we can allocate some inodes. Iterate through the
651 * allocation groups upward, wrapping 580 * allocation groups upward, wrapping at the end.
652 */ 581 */
653 *alloc_done = B_FALSE; 582 *alloc_done = B_FALSE;
654 while (!agi->agi_freecount) { !! 583 while (INT_ISZERO(agi->agi_freecount, ARCH_CONVERT)) {
655 /* 584 /*
656 * Don't do anything if we're 585 * Don't do anything if we're not supposed to allocate
657 * any blocks, just go on to t 586 * any blocks, just go on to the next ag.
658 */ 587 */
659 if (okalloc) { 588 if (okalloc) {
660 /* 589 /*
661 * Try to allocate som 590 * Try to allocate some new inodes in the allocation
662 * group. 591 * group.
663 */ 592 */
664 if ((error = xfs_iallo 593 if ((error = xfs_ialloc_ag_alloc(tp, agbp, &ialloced))) {
665 xfs_trans_brel 594 xfs_trans_brelse(tp, agbp);
666 if (error == E 595 if (error == ENOSPC) {
667 *inop 596 *inop = NULLFSINO;
668 return 597 return 0;
669 } else 598 } else
670 return 599 return error;
671 } 600 }
672 if (ialloced) { 601 if (ialloced) {
673 /* 602 /*
674 * We successf 603 * We successfully allocated some inodes, return
675 * the current 604 * the current context to the caller so that it
676 * can commit 605 * can commit the current transaction and call
677 * us again wh 606 * us again where we left off.
678 */ 607 */
679 ASSERT(be32_to !! 608 ASSERT(INT_GET(agi->agi_freecount, ARCH_CONVERT) > 0);
680 *alloc_done = 609 *alloc_done = B_TRUE;
681 *IO_agbp = agb 610 *IO_agbp = agbp;
682 *inop = NULLFS 611 *inop = NULLFSINO;
683 return 0; 612 return 0;
684 } 613 }
685 } 614 }
686 /* 615 /*
687 * If it failed, give up on th 616 * If it failed, give up on this ag.
688 */ 617 */
689 xfs_trans_brelse(tp, agbp); 618 xfs_trans_brelse(tp, agbp);
690 /* 619 /*
691 * Go on to the next ag: get i 620 * Go on to the next ag: get its ag header.
692 */ 621 */
693 nextag: 622 nextag:
694 if (++tagno == agcount) 623 if (++tagno == agcount)
695 tagno = 0; 624 tagno = 0;
696 if (tagno == agno) { 625 if (tagno == agno) {
697 *inop = NULLFSINO; 626 *inop = NULLFSINO;
698 return noroom ? ENOSPC 627 return noroom ? ENOSPC : 0;
699 } 628 }
700 down_read(&mp->m_peraglock); 629 down_read(&mp->m_peraglock);
701 if (mp->m_perag[tagno].pagi_in 630 if (mp->m_perag[tagno].pagi_inodeok == 0) {
702 up_read(&mp->m_peraglo 631 up_read(&mp->m_peraglock);
703 goto nextag; 632 goto nextag;
704 } 633 }
705 error = xfs_ialloc_read_agi(mp 634 error = xfs_ialloc_read_agi(mp, tp, tagno, &agbp);
706 up_read(&mp->m_peraglock); 635 up_read(&mp->m_peraglock);
707 if (error) 636 if (error)
708 goto nextag; 637 goto nextag;
709 agi = XFS_BUF_TO_AGI(agbp); 638 agi = XFS_BUF_TO_AGI(agbp);
710 ASSERT(be32_to_cpu(agi->agi_ma !! 639 ASSERT(INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC);
711 } 640 }
712 /* 641 /*
713 * Here with an allocation group that 642 * Here with an allocation group that has a free inode.
714 * Reset agno since we may have chosen 643 * Reset agno since we may have chosen a new ag in the
715 * loop above. 644 * loop above.
716 */ 645 */
717 agno = tagno; 646 agno = tagno;
718 *IO_agbp = NULL; 647 *IO_agbp = NULL;
719 cur = xfs_inobt_init_cursor(mp, tp, ag !! 648 cur = xfs_btree_init_cursor(mp, tp, agbp, INT_GET(agi->agi_seqno, ARCH_CONVERT),
>> 649 XFS_BTNUM_INO, (xfs_inode_t *)0, 0);
720 /* 650 /*
721 * If pagino is 0 (this is the root in 651 * If pagino is 0 (this is the root inode allocation) use newino.
722 * This must work because we've just a 652 * This must work because we've just allocated some.
723 */ 653 */
724 if (!pagino) 654 if (!pagino)
725 pagino = be32_to_cpu(agi->agi_ !! 655 pagino = INT_GET(agi->agi_newino, ARCH_CONVERT);
726 #ifdef DEBUG 656 #ifdef DEBUG
727 if (cur->bc_nlevels == 1) { 657 if (cur->bc_nlevels == 1) {
728 int freecount = 0; 658 int freecount = 0;
729 659
730 if ((error = xfs_inobt_lookup_ 660 if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
731 goto error0; 661 goto error0;
732 XFS_WANT_CORRUPTED_GOTO(i == 1 662 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
733 do { 663 do {
734 if ((error = xfs_inobt 664 if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino,
735 &rec.i !! 665 &rec.ir_freecount, &rec.ir_free, &i, ARCH_NOCONVERT)))
736 goto error0; 666 goto error0;
737 XFS_WANT_CORRUPTED_GOT 667 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
738 freecount += rec.ir_fr 668 freecount += rec.ir_freecount;
739 if ((error = xfs_btree !! 669 if ((error = xfs_inobt_increment(cur, 0, &i)))
740 goto error0; 670 goto error0;
741 } while (i == 1); 671 } while (i == 1);
742 672
743 ASSERT(freecount == be32_to_cp !! 673 ASSERT(freecount == INT_GET(agi->agi_freecount, ARCH_CONVERT) ||
744 XFS_FORCED_SHUTDOWN(mp) 674 XFS_FORCED_SHUTDOWN(mp));
745 } 675 }
746 #endif 676 #endif
747 /* 677 /*
748 * If in the same a.g. as the parent, 678 * If in the same a.g. as the parent, try to get near the parent.
749 */ 679 */
750 if (pagno == agno) { 680 if (pagno == agno) {
751 if ((error = xfs_inobt_lookup_ 681 if ((error = xfs_inobt_lookup_le(cur, pagino, 0, 0, &i)))
752 goto error0; 682 goto error0;
753 if (i != 0 && 683 if (i != 0 &&
754 (error = xfs_inobt_get_rec 684 (error = xfs_inobt_get_rec(cur, &rec.ir_startino,
755 &rec.ir_freecount, !! 685 &rec.ir_freecount, &rec.ir_free, &j, ARCH_NOCONVERT)) == 0 &&
756 j == 1 && 686 j == 1 &&
757 rec.ir_freecount > 0) { 687 rec.ir_freecount > 0) {
758 /* 688 /*
759 * Found a free inode 689 * Found a free inode in the same chunk
760 * as parent, done. 690 * as parent, done.
761 */ 691 */
762 } 692 }
763 /* 693 /*
764 * In the same a.g. as parent, 694 * In the same a.g. as parent, but parent's chunk is full.
765 */ 695 */
766 else { 696 else {
767 int doneleft; 697 int doneleft; /* done, to the left */
768 int doneright; 698 int doneright; /* done, to the right */
769 699
770 if (error) 700 if (error)
771 goto error0; 701 goto error0;
772 ASSERT(i == 1); 702 ASSERT(i == 1);
773 ASSERT(j == 1); 703 ASSERT(j == 1);
774 /* 704 /*
775 * Duplicate the curso 705 * Duplicate the cursor, search left & right
776 * simultaneously. 706 * simultaneously.
777 */ 707 */
778 if ((error = xfs_btree 708 if ((error = xfs_btree_dup_cursor(cur, &tcur)))
779 goto error0; 709 goto error0;
780 /* 710 /*
781 * Search left with tc 711 * Search left with tcur, back up 1 record.
782 */ 712 */
783 if ((error = xfs_btree !! 713 if ((error = xfs_inobt_decrement(tcur, 0, &i)))
784 goto error1; 714 goto error1;
785 doneleft = !i; 715 doneleft = !i;
786 if (!doneleft) { 716 if (!doneleft) {
787 if ((error = x 717 if ((error = xfs_inobt_get_rec(tcur,
788 718 &trec.ir_startino,
789 719 &trec.ir_freecount,
790 !! 720 &trec.ir_free, &i, ARCH_NOCONVERT)))
791 goto e 721 goto error1;
792 XFS_WANT_CORRU 722 XFS_WANT_CORRUPTED_GOTO(i == 1, error1);
793 } 723 }
794 /* 724 /*
795 * Search right with c 725 * Search right with cur, go forward 1 record.
796 */ 726 */
797 if ((error = xfs_btree !! 727 if ((error = xfs_inobt_increment(cur, 0, &i)))
798 goto error1; 728 goto error1;
799 doneright = !i; 729 doneright = !i;
800 if (!doneright) { 730 if (!doneright) {
801 if ((error = x 731 if ((error = xfs_inobt_get_rec(cur,
802 732 &rec.ir_startino,
803 733 &rec.ir_freecount,
804 !! 734 &rec.ir_free, &i, ARCH_NOCONVERT)))
805 goto e 735 goto error1;
806 XFS_WANT_CORRU 736 XFS_WANT_CORRUPTED_GOTO(i == 1, error1);
807 } 737 }
808 /* 738 /*
809 * Loop until we find 739 * Loop until we find the closest inode chunk
810 * with a free one. 740 * with a free one.
811 */ 741 */
812 while (!doneleft || !d 742 while (!doneleft || !doneright) {
813 int uselef 743 int useleft; /* using left inode
814 744 chunk this time */
815 745
816 /* 746 /*
817 * Figure out 747 * Figure out which block is closer,
818 * if both are 748 * if both are valid.
819 */ 749 */
820 if (!doneleft 750 if (!doneleft && !doneright)
821 uselef 751 useleft =
822 752 pagino -
823 753 (trec.ir_startino +
824 754 XFS_INODES_PER_CHUNK - 1) <
825 755 rec.ir_startino - pagino;
826 else 756 else
827 uselef 757 useleft = !doneleft;
828 /* 758 /*
829 * If checking 759 * If checking the left, does it have
830 * free inodes 760 * free inodes?
831 */ 761 */
832 if (useleft && 762 if (useleft && trec.ir_freecount) {
833 /* 763 /*
834 * Yes 764 * Yes, set it up as the chunk to use.
835 */ 765 */
836 rec = 766 rec = trec;
837 xfs_bt 767 xfs_btree_del_cursor(cur,
838 768 XFS_BTREE_NOERROR);
839 cur = 769 cur = tcur;
840 break; 770 break;
841 } 771 }
842 /* 772 /*
843 * If checking 773 * If checking the right, does it have
844 * free inodes 774 * free inodes?
845 */ 775 */
846 if (!useleft & 776 if (!useleft && rec.ir_freecount) {
847 /* 777 /*
848 * Yes 778 * Yes, it's already set up.
849 */ 779 */
850 xfs_bt 780 xfs_btree_del_cursor(tcur,
851 781 XFS_BTREE_NOERROR);
852 break; 782 break;
853 } 783 }
854 /* 784 /*
855 * If used the 785 * If used the left, get another one
856 * further lef 786 * further left.
857 */ 787 */
858 if (useleft) { 788 if (useleft) {
859 if ((e !! 789 if ((error = xfs_inobt_decrement(tcur, 0,
860 790 &i)))
861 791 goto error1;
862 donele 792 doneleft = !i;
863 if (!d 793 if (!doneleft) {
864 794 if ((error = xfs_inobt_get_rec(
865 795 tcur,
866 796 &trec.ir_startino,
867 797 &trec.ir_freecount,
868 !! 798 &trec.ir_free, &i, ARCH_NOCONVERT)))
869 799 goto error1;
870 800 XFS_WANT_CORRUPTED_GOTO(i == 1,
871 801 error1);
872 } 802 }
873 } 803 }
874 /* 804 /*
875 * If used the 805 * If used the right, get another one
876 * further rig 806 * further right.
877 */ 807 */
878 else { 808 else {
879 if ((e !! 809 if ((error = xfs_inobt_increment(cur, 0,
880 810 &i)))
881 811 goto error1;
882 doneri 812 doneright = !i;
883 if (!d 813 if (!doneright) {
884 814 if ((error = xfs_inobt_get_rec(
885 815 cur,
886 816 &rec.ir_startino,
887 817 &rec.ir_freecount,
888 !! 818 &rec.ir_free, &i, ARCH_NOCONVERT)))
889 819 goto error1;
890 820 XFS_WANT_CORRUPTED_GOTO(i == 1,
891 821 error1);
892 } 822 }
893 } 823 }
894 } 824 }
895 ASSERT(!doneleft || !d 825 ASSERT(!doneleft || !doneright);
896 } 826 }
897 } 827 }
898 /* 828 /*
899 * In a different a.g. from the parent 829 * In a different a.g. from the parent.
900 * See if the most recently allocated 830 * See if the most recently allocated block has any free.
901 */ 831 */
902 else if (be32_to_cpu(agi->agi_newino) !! 832 else if (INT_GET(agi->agi_newino, ARCH_CONVERT) != NULLAGINO) {
903 if ((error = xfs_inobt_lookup_ 833 if ((error = xfs_inobt_lookup_eq(cur,
904 be32_to_cpu(ag !! 834 INT_GET(agi->agi_newino, ARCH_CONVERT), 0, 0, &i)))
905 goto error0; 835 goto error0;
906 if (i == 1 && 836 if (i == 1 &&
907 (error = xfs_inobt_get_rec 837 (error = xfs_inobt_get_rec(cur, &rec.ir_startino,
908 &rec.ir_freecount, !! 838 &rec.ir_freecount, &rec.ir_free, &j, ARCH_NOCONVERT)) == 0 &&
909 j == 1 && 839 j == 1 &&
910 rec.ir_freecount > 0) { 840 rec.ir_freecount > 0) {
911 /* 841 /*
912 * The last chunk allo 842 * The last chunk allocated in the group still has
913 * a free inode. 843 * a free inode.
914 */ 844 */
915 } 845 }
916 /* 846 /*
917 * None left in the last group 847 * None left in the last group, search the whole a.g.
918 */ 848 */
919 else { 849 else {
920 if (error) 850 if (error)
921 goto error0; 851 goto error0;
922 if ((error = xfs_inobt 852 if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
923 goto error0; 853 goto error0;
924 ASSERT(i == 1); 854 ASSERT(i == 1);
925 for (;;) { 855 for (;;) {
926 if ((error = x 856 if ((error = xfs_inobt_get_rec(cur,
927 857 &rec.ir_startino,
928 858 &rec.ir_freecount, &rec.ir_free,
929 !! 859 &i, ARCH_NOCONVERT)))
930 goto e 860 goto error0;
931 XFS_WANT_CORRU 861 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
932 if (rec.ir_fre 862 if (rec.ir_freecount > 0)
933 break; 863 break;
934 if ((error = x !! 864 if ((error = xfs_inobt_increment(cur, 0, &i)))
935 goto e 865 goto error0;
936 XFS_WANT_CORRU 866 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
937 } 867 }
938 } 868 }
939 } 869 }
940 offset = xfs_ialloc_find_free(&rec.ir_ !! 870 offset = XFS_IALLOC_FIND_FREE(&rec.ir_free);
941 ASSERT(offset >= 0); 871 ASSERT(offset >= 0);
942 ASSERT(offset < XFS_INODES_PER_CHUNK); 872 ASSERT(offset < XFS_INODES_PER_CHUNK);
943 ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir 873 ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) %
944 XFS_INODES_ 874 XFS_INODES_PER_CHUNK) == 0);
945 ino = XFS_AGINO_TO_INO(mp, agno, rec.i 875 ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino + offset);
946 rec.ir_free &= ~XFS_INOBT_MASK(offset) !! 876 XFS_INOBT_CLR_FREE(&rec, offset, ARCH_NOCONVERT);
947 rec.ir_freecount--; 877 rec.ir_freecount--;
948 if ((error = xfs_inobt_update(cur, rec 878 if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount,
949 rec.ir_free))) 879 rec.ir_free)))
950 goto error0; 880 goto error0;
951 be32_add_cpu(&agi->agi_freecount, -1); !! 881 INT_MOD(agi->agi_freecount, ARCH_CONVERT, -1);
952 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_F 882 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
953 down_read(&mp->m_peraglock); 883 down_read(&mp->m_peraglock);
954 mp->m_perag[tagno].pagi_freecount--; 884 mp->m_perag[tagno].pagi_freecount--;
955 up_read(&mp->m_peraglock); 885 up_read(&mp->m_peraglock);
956 #ifdef DEBUG 886 #ifdef DEBUG
957 if (cur->bc_nlevels == 1) { 887 if (cur->bc_nlevels == 1) {
958 int freecount = 0; 888 int freecount = 0;
959 889
960 if ((error = xfs_inobt_lookup_ 890 if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
961 goto error0; 891 goto error0;
962 do { 892 do {
963 if ((error = xfs_inobt 893 if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino,
964 &rec.i !! 894 &rec.ir_freecount, &rec.ir_free, &i, ARCH_NOCONVERT)))
965 goto error0; 895 goto error0;
966 XFS_WANT_CORRUPTED_GOT 896 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
967 freecount += rec.ir_fr 897 freecount += rec.ir_freecount;
968 if ((error = xfs_btree !! 898 if ((error = xfs_inobt_increment(cur, 0, &i)))
969 goto error0; 899 goto error0;
970 } while (i == 1); 900 } while (i == 1);
971 ASSERT(freecount == be32_to_cp !! 901 ASSERT(freecount == INT_GET(agi->agi_freecount, ARCH_CONVERT) ||
972 XFS_FORCED_SHUTDOWN(mp) 902 XFS_FORCED_SHUTDOWN(mp));
973 } 903 }
974 #endif 904 #endif
975 xfs_btree_del_cursor(cur, XFS_BTREE_NO 905 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
976 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFRE 906 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1);
977 *inop = ino; 907 *inop = ino;
978 return 0; 908 return 0;
979 error1: 909 error1:
980 xfs_btree_del_cursor(tcur, XFS_BTREE_E 910 xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
981 error0: 911 error0:
982 xfs_btree_del_cursor(cur, XFS_BTREE_ER 912 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
983 return error; 913 return error;
984 } 914 }
985 915
986 /* 916 /*
987 * Free disk inode. Carefully avoids touching 917 * Free disk inode. Carefully avoids touching the incore inode, all
988 * manipulations incore are the caller's respo 918 * manipulations incore are the caller's responsibility.
989 * The on-disk inode is not changed by this op 919 * The on-disk inode is not changed by this operation, only the
990 * btree (free inode mask) is changed. 920 * btree (free inode mask) is changed.
991 */ 921 */
992 int 922 int
993 xfs_difree( 923 xfs_difree(
994 xfs_trans_t *tp, /* tra 924 xfs_trans_t *tp, /* transaction pointer */
995 xfs_ino_t inode, /* ino 925 xfs_ino_t inode, /* inode to be freed */
996 xfs_bmap_free_t *flist, /* ext 926 xfs_bmap_free_t *flist, /* extents to free */
997 int *delete, /* set 927 int *delete, /* set if inode cluster was deleted */
998 xfs_ino_t *first_ino) /* fir 928 xfs_ino_t *first_ino) /* first inode in deleted cluster */
999 { 929 {
1000 /* REFERENCED */ 930 /* REFERENCED */
1001 xfs_agblock_t agbno; /* block numb 931 xfs_agblock_t agbno; /* block number containing inode */
1002 xfs_buf_t *agbp; /* buffer con 932 xfs_buf_t *agbp; /* buffer containing allocation group header */
1003 xfs_agino_t agino; /* inode numb 933 xfs_agino_t agino; /* inode number relative to allocation group */
1004 xfs_agnumber_t agno; /* allocation 934 xfs_agnumber_t agno; /* allocation group number */
1005 xfs_agi_t *agi; /* allocation 935 xfs_agi_t *agi; /* allocation group header */
1006 xfs_btree_cur_t *cur; /* inode btre 936 xfs_btree_cur_t *cur; /* inode btree cursor */
1007 int error; /* error retu 937 int error; /* error return value */
1008 int i; /* result cod 938 int i; /* result code */
1009 int ilen; /* inodes in 939 int ilen; /* inodes in an inode cluster */
1010 xfs_mount_t *mp; /* mount stru 940 xfs_mount_t *mp; /* mount structure for filesystem */
1011 int off; /* offset of 941 int off; /* offset of inode in inode chunk */
1012 xfs_inobt_rec_incore_t rec; /* bt !! 942 xfs_inobt_rec_t rec; /* btree record */
1013 943
1014 mp = tp->t_mountp; 944 mp = tp->t_mountp;
1015 945
1016 /* 946 /*
1017 * Break up inode number into its com 947 * Break up inode number into its components.
1018 */ 948 */
1019 agno = XFS_INO_TO_AGNO(mp, inode); 949 agno = XFS_INO_TO_AGNO(mp, inode);
1020 if (agno >= mp->m_sb.sb_agcount) { 950 if (agno >= mp->m_sb.sb_agcount) {
1021 cmn_err(CE_WARN, 951 cmn_err(CE_WARN,
1022 "xfs_difree: agno >= 952 "xfs_difree: agno >= mp->m_sb.sb_agcount (%d >= %d) on %s. Returning EINVAL.",
1023 agno, mp->m_sb.sb_agc 953 agno, mp->m_sb.sb_agcount, mp->m_fsname);
1024 ASSERT(0); 954 ASSERT(0);
1025 return XFS_ERROR(EINVAL); 955 return XFS_ERROR(EINVAL);
1026 } 956 }
1027 agino = XFS_INO_TO_AGINO(mp, inode); 957 agino = XFS_INO_TO_AGINO(mp, inode);
1028 if (inode != XFS_AGINO_TO_INO(mp, agn 958 if (inode != XFS_AGINO_TO_INO(mp, agno, agino)) {
1029 cmn_err(CE_WARN, 959 cmn_err(CE_WARN,
1030 "xfs_difree: inode != !! 960 "xfs_difree: inode != XFS_AGINO_TO_INO() (%d != %d) on %s. Returning EINVAL.",
1031 "(%llu != %llu) on %s !! 961 inode, XFS_AGINO_TO_INO(mp, agno, agino), mp->m_fsname);
1032 (unsigned long long)i <<
1033 (unsigned long long)X <<
1034 mp->m_fsname); <<
1035 ASSERT(0); 962 ASSERT(0);
1036 return XFS_ERROR(EINVAL); 963 return XFS_ERROR(EINVAL);
1037 } 964 }
1038 agbno = XFS_AGINO_TO_AGBNO(mp, agino) 965 agbno = XFS_AGINO_TO_AGBNO(mp, agino);
1039 if (agbno >= mp->m_sb.sb_agblocks) { 966 if (agbno >= mp->m_sb.sb_agblocks) {
1040 cmn_err(CE_WARN, 967 cmn_err(CE_WARN,
1041 "xfs_difree: agbno >= 968 "xfs_difree: agbno >= mp->m_sb.sb_agblocks (%d >= %d) on %s. Returning EINVAL.",
1042 agbno, mp->m_sb.sb_ag 969 agbno, mp->m_sb.sb_agblocks, mp->m_fsname);
1043 ASSERT(0); 970 ASSERT(0);
1044 return XFS_ERROR(EINVAL); 971 return XFS_ERROR(EINVAL);
1045 } 972 }
1046 /* 973 /*
1047 * Get the allocation group header. 974 * Get the allocation group header.
1048 */ 975 */
1049 down_read(&mp->m_peraglock); 976 down_read(&mp->m_peraglock);
1050 error = xfs_ialloc_read_agi(mp, tp, a 977 error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
1051 up_read(&mp->m_peraglock); 978 up_read(&mp->m_peraglock);
1052 if (error) { 979 if (error) {
1053 cmn_err(CE_WARN, 980 cmn_err(CE_WARN,
1054 "xfs_difree: xfs_iall 981 "xfs_difree: xfs_ialloc_read_agi() returned an error %d on %s. Returning error.",
1055 error, mp->m_fsname); 982 error, mp->m_fsname);
1056 return error; 983 return error;
1057 } 984 }
1058 agi = XFS_BUF_TO_AGI(agbp); 985 agi = XFS_BUF_TO_AGI(agbp);
1059 ASSERT(be32_to_cpu(agi->agi_magicnum) !! 986 ASSERT(INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC);
1060 ASSERT(agbno < be32_to_cpu(agi->agi_l !! 987 ASSERT(agbno < INT_GET(agi->agi_length, ARCH_CONVERT));
1061 /* 988 /*
1062 * Initialize the cursor. 989 * Initialize the cursor.
1063 */ 990 */
1064 cur = xfs_inobt_init_cursor(mp, tp, a !! 991 cur = xfs_btree_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO,
>> 992 (xfs_inode_t *)0, 0);
1065 #ifdef DEBUG 993 #ifdef DEBUG
1066 if (cur->bc_nlevels == 1) { 994 if (cur->bc_nlevels == 1) {
1067 int freecount = 0; 995 int freecount = 0;
1068 996
1069 if ((error = xfs_inobt_lookup 997 if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
1070 goto error0; 998 goto error0;
1071 do { 999 do {
1072 if ((error = xfs_inob 1000 if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino,
1073 &rec. !! 1001 &rec.ir_freecount, &rec.ir_free, &i, ARCH_NOCONVERT)))
1074 goto error0; 1002 goto error0;
1075 if (i) { 1003 if (i) {
1076 freecount += 1004 freecount += rec.ir_freecount;
1077 if ((error = !! 1005 if ((error = xfs_inobt_increment(cur, 0, &i)))
1078 goto 1006 goto error0;
1079 } 1007 }
1080 } while (i == 1); 1008 } while (i == 1);
1081 ASSERT(freecount == be32_to_c !! 1009 ASSERT(freecount == INT_GET(agi->agi_freecount, ARCH_CONVERT) ||
1082 XFS_FORCED_SHUTDOWN(mp 1010 XFS_FORCED_SHUTDOWN(mp));
1083 } 1011 }
1084 #endif 1012 #endif
1085 /* 1013 /*
1086 * Look for the entry describing this 1014 * Look for the entry describing this inode.
1087 */ 1015 */
1088 if ((error = xfs_inobt_lookup_le(cur, 1016 if ((error = xfs_inobt_lookup_le(cur, agino, 0, 0, &i))) {
1089 cmn_err(CE_WARN, 1017 cmn_err(CE_WARN,
1090 "xfs_difree: xfs_inob 1018 "xfs_difree: xfs_inobt_lookup_le returned() an error %d on %s. Returning error.",
1091 error, mp->m_fsname); 1019 error, mp->m_fsname);
1092 goto error0; 1020 goto error0;
1093 } 1021 }
1094 XFS_WANT_CORRUPTED_GOTO(i == 1, error 1022 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1095 if ((error = xfs_inobt_get_rec(cur, & 1023 if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino, &rec.ir_freecount,
1096 &rec.ir_free, &i))) { !! 1024 &rec.ir_free, &i, ARCH_NOCONVERT))) {
1097 cmn_err(CE_WARN, 1025 cmn_err(CE_WARN,
1098 "xfs_difree: xfs_inob 1026 "xfs_difree: xfs_inobt_get_rec() returned an error %d on %s. Returning error.",
1099 error, mp->m_fsname); 1027 error, mp->m_fsname);
1100 goto error0; 1028 goto error0;
1101 } 1029 }
1102 XFS_WANT_CORRUPTED_GOTO(i == 1, error 1030 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1103 /* 1031 /*
1104 * Get the offset in the inode chunk. 1032 * Get the offset in the inode chunk.
1105 */ 1033 */
1106 off = agino - rec.ir_startino; 1034 off = agino - rec.ir_startino;
1107 ASSERT(off >= 0 && off < XFS_INODES_P 1035 ASSERT(off >= 0 && off < XFS_INODES_PER_CHUNK);
1108 ASSERT(!(rec.ir_free & XFS_INOBT_MASK !! 1036 ASSERT(!XFS_INOBT_IS_FREE(&rec, off, ARCH_NOCONVERT));
1109 /* 1037 /*
1110 * Mark the inode free & increment th 1038 * Mark the inode free & increment the count.
1111 */ 1039 */
1112 rec.ir_free |= XFS_INOBT_MASK(off); !! 1040 XFS_INOBT_SET_FREE(&rec, off, ARCH_NOCONVERT);
1113 rec.ir_freecount++; 1041 rec.ir_freecount++;
1114 1042
1115 /* 1043 /*
1116 * When an inode cluster is free, it !! 1044 * When an inode cluster is free, it becomes elgible for removal
1117 */ 1045 */
1118 if (!(mp->m_flags & XFS_MOUNT_IKEEP) !! 1046 if ((mp->m_flags & XFS_MOUNT_IDELETE) &&
1119 (rec.ir_freecount == XFS_IALLOC_I 1047 (rec.ir_freecount == XFS_IALLOC_INODES(mp))) {
1120 1048
1121 *delete = 1; 1049 *delete = 1;
1122 *first_ino = XFS_AGINO_TO_INO 1050 *first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino);
1123 1051
1124 /* 1052 /*
1125 * Remove the inode cluster f 1053 * Remove the inode cluster from the AGI B+Tree, adjust the
1126 * AGI and Superblock inode c 1054 * AGI and Superblock inode counts, and mark the disk space
1127 * to be freed when the trans 1055 * to be freed when the transaction is committed.
1128 */ 1056 */
1129 ilen = XFS_IALLOC_INODES(mp); 1057 ilen = XFS_IALLOC_INODES(mp);
1130 be32_add_cpu(&agi->agi_count, !! 1058 INT_MOD(agi->agi_count, ARCH_CONVERT, -ilen);
1131 be32_add_cpu(&agi->agi_freeco !! 1059 INT_MOD(agi->agi_freecount, ARCH_CONVERT, -(ilen - 1));
1132 xfs_ialloc_log_agi(tp, agbp, 1060 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT);
1133 down_read(&mp->m_peraglock); 1061 down_read(&mp->m_peraglock);
1134 mp->m_perag[agno].pagi_freeco 1062 mp->m_perag[agno].pagi_freecount -= ilen - 1;
1135 up_read(&mp->m_peraglock); 1063 up_read(&mp->m_peraglock);
1136 xfs_trans_mod_sb(tp, XFS_TRAN 1064 xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, -ilen);
1137 xfs_trans_mod_sb(tp, XFS_TRAN 1065 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -(ilen - 1));
1138 1066
1139 if ((error = xfs_btree_delete !! 1067 if ((error = xfs_inobt_delete(cur, &i))) {
1140 cmn_err(CE_WARN, "xfs !! 1068 cmn_err(CE_WARN, "xfs_difree: xfs_inobt_delete returned an error %d on %s.\n",
1141 error, mp->m_ 1069 error, mp->m_fsname);
1142 goto error0; 1070 goto error0;
1143 } 1071 }
1144 1072
1145 xfs_bmap_add_free(XFS_AGB_TO_ 1073 xfs_bmap_add_free(XFS_AGB_TO_FSB(mp,
1146 agno, XFS_INO 1074 agno, XFS_INO_TO_AGBNO(mp,rec.ir_startino)),
1147 XFS_IALLOC_BL 1075 XFS_IALLOC_BLOCKS(mp), flist, mp);
1148 } else { 1076 } else {
1149 *delete = 0; 1077 *delete = 0;
1150 1078
1151 if ((error = xfs_inobt_update 1079 if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount, rec.ir_free))) {
1152 cmn_err(CE_WARN, 1080 cmn_err(CE_WARN,
1153 "xfs_difree: 1081 "xfs_difree: xfs_inobt_update() returned an error %d on %s. Returning error.",
1154 error, mp->m_ 1082 error, mp->m_fsname);
1155 goto error0; 1083 goto error0;
1156 } 1084 }
1157 /* 1085 /*
1158 * Change the inode free coun 1086 * Change the inode free counts and log the ag/sb changes.
1159 */ 1087 */
1160 be32_add_cpu(&agi->agi_freeco !! 1088 INT_MOD(agi->agi_freecount, ARCH_CONVERT, 1);
1161 xfs_ialloc_log_agi(tp, agbp, 1089 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
1162 down_read(&mp->m_peraglock); 1090 down_read(&mp->m_peraglock);
1163 mp->m_perag[agno].pagi_freeco 1091 mp->m_perag[agno].pagi_freecount++;
1164 up_read(&mp->m_peraglock); 1092 up_read(&mp->m_peraglock);
1165 xfs_trans_mod_sb(tp, XFS_TRAN 1093 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1);
1166 } 1094 }
1167 1095
1168 #ifdef DEBUG 1096 #ifdef DEBUG
1169 if (cur->bc_nlevels == 1) { 1097 if (cur->bc_nlevels == 1) {
1170 int freecount = 0; 1098 int freecount = 0;
1171 1099
1172 if ((error = xfs_inobt_lookup 1100 if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
1173 goto error0; 1101 goto error0;
1174 do { 1102 do {
1175 if ((error = xfs_inob 1103 if ((error = xfs_inobt_get_rec(cur,
1176 &rec. 1104 &rec.ir_startino,
1177 &rec. 1105 &rec.ir_freecount,
1178 &rec. !! 1106 &rec.ir_free, &i,
>> 1107 ARCH_NOCONVERT)))
1179 goto error0; 1108 goto error0;
1180 if (i) { 1109 if (i) {
1181 freecount += 1110 freecount += rec.ir_freecount;
1182 if ((error = !! 1111 if ((error = xfs_inobt_increment(cur, 0, &i)))
1183 goto 1112 goto error0;
1184 } 1113 }
1185 } while (i == 1); 1114 } while (i == 1);
1186 ASSERT(freecount == be32_to_c !! 1115 ASSERT(freecount == INT_GET(agi->agi_freecount, ARCH_CONVERT) ||
1187 XFS_FORCED_SHUTDOWN(mp 1116 XFS_FORCED_SHUTDOWN(mp));
1188 } 1117 }
1189 #endif 1118 #endif
1190 xfs_btree_del_cursor(cur, XFS_BTREE_N 1119 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
1191 return 0; 1120 return 0;
1192 1121
1193 error0: 1122 error0:
1194 xfs_btree_del_cursor(cur, XFS_BTREE_E 1123 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
1195 return error; 1124 return error;
1196 } 1125 }
1197 1126
1198 /* 1127 /*
1199 * Return the location of the inode in imap, !! 1128 * Return the location of the inode in bno/off, for mapping it into a buffer.
1200 */ 1129 */
>> 1130 /*ARGSUSED*/
1201 int 1131 int
1202 xfs_imap( !! 1132 xfs_dilocate(
1203 xfs_mount_t *mp, /* file syste !! 1133 xfs_mount_t *mp, /* file system mount structure */
1204 xfs_trans_t *tp, /* transactio !! 1134 xfs_trans_t *tp, /* transaction pointer */
1205 xfs_ino_t ino, /* inode to l 1135 xfs_ino_t ino, /* inode to locate */
1206 struct xfs_imap *imap, /* location m !! 1136 xfs_fsblock_t *bno, /* output: block containing inode */
1207 uint flags) /* flags for !! 1137 int *len, /* output: num blocks in inode cluster */
>> 1138 int *off, /* output: index in block of inode */
>> 1139 uint flags) /* flags concerning inode lookup */
1208 { 1140 {
1209 xfs_agblock_t agbno; /* block numb 1141 xfs_agblock_t agbno; /* block number of inode in the alloc group */
>> 1142 xfs_buf_t *agbp; /* agi buffer */
1210 xfs_agino_t agino; /* inode numb 1143 xfs_agino_t agino; /* inode number within alloc group */
1211 xfs_agnumber_t agno; /* allocation 1144 xfs_agnumber_t agno; /* allocation group number */
1212 int blks_per_cluster; /* 1145 int blks_per_cluster; /* num blocks per inode cluster */
1213 xfs_agblock_t chunk_agbno; /* fi 1146 xfs_agblock_t chunk_agbno; /* first block in inode chunk */
>> 1147 xfs_agino_t chunk_agino; /* first agino in inode chunk */
>> 1148 __int32_t chunk_cnt; /* count of free inodes in chunk */
>> 1149 xfs_inofree_t chunk_free; /* mask of free inodes in chunk */
1214 xfs_agblock_t cluster_agbno; /* fi 1150 xfs_agblock_t cluster_agbno; /* first block in inode cluster */
>> 1151 xfs_btree_cur_t *cur; /* inode btree cursor */
1215 int error; /* error code 1152 int error; /* error code */
>> 1153 int i; /* temp state */
1216 int offset; /* index of i 1154 int offset; /* index of inode in its buffer */
1217 int offset_agbno; /* bl 1155 int offset_agbno; /* blks from chunk start to inode */
1218 1156
1219 ASSERT(ino != NULLFSINO); 1157 ASSERT(ino != NULLFSINO);
1220 <<
1221 /* 1158 /*
1222 * Split up the inode number into its 1159 * Split up the inode number into its parts.
1223 */ 1160 */
1224 agno = XFS_INO_TO_AGNO(mp, ino); 1161 agno = XFS_INO_TO_AGNO(mp, ino);
1225 agino = XFS_INO_TO_AGINO(mp, ino); 1162 agino = XFS_INO_TO_AGINO(mp, ino);
1226 agbno = XFS_AGINO_TO_AGBNO(mp, agino) 1163 agbno = XFS_AGINO_TO_AGBNO(mp, agino);
1227 if (agno >= mp->m_sb.sb_agcount || ag 1164 if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
1228 ino != XFS_AGINO_TO_INO(mp, agno, 1165 ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
1229 #ifdef DEBUG 1166 #ifdef DEBUG
1230 /* no diagnostics for bulksta <<
1231 if (flags & XFS_IGET_BULKSTAT <<
1232 return XFS_ERROR(EINV <<
1233 if (agno >= mp->m_sb.sb_agcou 1167 if (agno >= mp->m_sb.sb_agcount) {
1234 xfs_fs_cmn_err(CE_ALE 1168 xfs_fs_cmn_err(CE_ALERT, mp,
1235 "xfs_ !! 1169 "xfs_dilocate: agno (%d) >= "
1236 "mp-> 1170 "mp->m_sb.sb_agcount (%d)",
1237 agno, 1171 agno, mp->m_sb.sb_agcount);
1238 } 1172 }
1239 if (agbno >= mp->m_sb.sb_agbl 1173 if (agbno >= mp->m_sb.sb_agblocks) {
1240 xfs_fs_cmn_err(CE_ALE 1174 xfs_fs_cmn_err(CE_ALERT, mp,
1241 "xfs_ !! 1175 "xfs_dilocate: agbno (0x%llx) >= "
1242 "mp-> 1176 "mp->m_sb.sb_agblocks (0x%lx)",
1243 (unsi 1177 (unsigned long long) agbno,
1244 (unsi 1178 (unsigned long) mp->m_sb.sb_agblocks);
1245 } 1179 }
1246 if (ino != XFS_AGINO_TO_INO(m 1180 if (ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
1247 xfs_fs_cmn_err(CE_ALE 1181 xfs_fs_cmn_err(CE_ALERT, mp,
1248 "xfs_ !! 1182 "xfs_dilocate: ino (0x%llx) != "
1249 "XFS_ 1183 "XFS_AGINO_TO_INO(mp, agno, agino) "
1250 "(0x% 1184 "(0x%llx)",
1251 ino, 1185 ino, XFS_AGINO_TO_INO(mp, agno, agino));
1252 } 1186 }
1253 xfs_stack_trace(); <<
1254 #endif /* DEBUG */ 1187 #endif /* DEBUG */
1255 return XFS_ERROR(EINVAL); 1188 return XFS_ERROR(EINVAL);
1256 } 1189 }
1257 !! 1190 if ((mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) ||
1258 /* !! 1191 !(flags & XFS_IMAP_LOOKUP)) {
1259 * If the inode cluster size is the s <<
1260 * smaller we get to the buffer by si <<
1261 */ <<
1262 if (XFS_INODE_CLUSTER_SIZE(mp) <= mp- <<
1263 offset = XFS_INO_TO_OFFSET(mp 1192 offset = XFS_INO_TO_OFFSET(mp, ino);
1264 ASSERT(offset < mp->m_sb.sb_i 1193 ASSERT(offset < mp->m_sb.sb_inopblock);
1265 !! 1194 *bno = XFS_AGB_TO_FSB(mp, agno, agbno);
1266 imap->im_blkno = XFS_AGB_TO_D !! 1195 *off = offset;
1267 imap->im_len = XFS_FSB_TO_BB( !! 1196 *len = 1;
1268 imap->im_boffset = (ushort)(o <<
1269 return 0; 1197 return 0;
1270 } 1198 }
1271 <<
1272 blks_per_cluster = XFS_INODE_CLUSTER_ 1199 blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_blocklog;
1273 !! 1200 if (*bno != NULLFSBLOCK) {
1274 /* <<
1275 * If we get a block number passed fr <<
1276 * find the buffer easily. <<
1277 */ <<
1278 if (imap->im_blkno) { <<
1279 offset = XFS_INO_TO_OFFSET(mp 1201 offset = XFS_INO_TO_OFFSET(mp, ino);
1280 ASSERT(offset < mp->m_sb.sb_i 1202 ASSERT(offset < mp->m_sb.sb_inopblock);
1281 !! 1203 cluster_agbno = XFS_FSB_TO_AGBNO(mp, *bno);
1282 cluster_agbno = xfs_daddr_to_ !! 1204 *off = ((agbno - cluster_agbno) * mp->m_sb.sb_inopblock) +
1283 offset += (agbno - cluster_ag !! 1205 offset;
1284 !! 1206 *len = blks_per_cluster;
1285 imap->im_len = XFS_FSB_TO_BB( <<
1286 imap->im_boffset = (ushort)(o <<
1287 return 0; 1207 return 0;
1288 } 1208 }
1289 <<
1290 /* <<
1291 * If the inode chunks are aligned th <<
1292 * find the location. Otherwise we ha <<
1293 * lookup to find the location. <<
1294 */ <<
1295 if (mp->m_inoalign_mask) { 1209 if (mp->m_inoalign_mask) {
1296 offset_agbno = agbno & mp->m_ 1210 offset_agbno = agbno & mp->m_inoalign_mask;
1297 chunk_agbno = agbno - offset_ 1211 chunk_agbno = agbno - offset_agbno;
1298 } else { 1212 } else {
1299 xfs_btree_cur_t *cur; /* in <<
1300 xfs_agino_t chunk_agino; <<
1301 __int32_t chunk_cnt; /* <<
1302 xfs_inofree_t chunk_free; / <<
1303 xfs_buf_t *agbp; /* ag <<
1304 int i; /* te <<
1305 <<
1306 down_read(&mp->m_peraglock); 1213 down_read(&mp->m_peraglock);
1307 error = xfs_ialloc_read_agi(m 1214 error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
1308 up_read(&mp->m_peraglock); 1215 up_read(&mp->m_peraglock);
1309 if (error) { 1216 if (error) {
1310 xfs_fs_cmn_err(CE_ALE !! 1217 #ifdef DEBUG
>> 1218 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_dilocate: "
1311 "xfs_ 1219 "xfs_ialloc_read_agi() returned "
1312 "erro 1220 "error %d, agno %d",
1313 error 1221 error, agno);
>> 1222 #endif /* DEBUG */
1314 return error; 1223 return error;
1315 } 1224 }
1316 !! 1225 cur = xfs_btree_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO,
1317 cur = xfs_inobt_init_cursor(m !! 1226 (xfs_inode_t *)0, 0);
1318 error = xfs_inobt_lookup_le(c !! 1227 if ((error = xfs_inobt_lookup_le(cur, agino, 0, 0, &i))) {
1319 if (error) { !! 1228 #ifdef DEBUG
1320 xfs_fs_cmn_err(CE_ALE !! 1229 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_dilocate: "
1321 "xfs_ 1230 "xfs_inobt_lookup_le() failed");
>> 1231 #endif /* DEBUG */
1322 goto error0; 1232 goto error0;
1323 } 1233 }
1324 !! 1234 if ((error = xfs_inobt_get_rec(cur, &chunk_agino, &chunk_cnt,
1325 error = xfs_inobt_get_rec(cur !! 1235 &chunk_free, &i, ARCH_NOCONVERT))) {
1326 &chunk_free, !! 1236 #ifdef DEBUG
1327 if (error) { !! 1237 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_dilocate: "
1328 xfs_fs_cmn_err(CE_ALE <<
1329 "xfs_ 1238 "xfs_inobt_get_rec() failed");
>> 1239 #endif /* DEBUG */
1330 goto error0; 1240 goto error0;
1331 } 1241 }
1332 if (i == 0) { 1242 if (i == 0) {
1333 #ifdef DEBUG 1243 #ifdef DEBUG
1334 xfs_fs_cmn_err(CE_ALE !! 1244 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_dilocate: "
1335 "xfs_ 1245 "xfs_inobt_get_rec() failed");
1336 #endif /* DEBUG */ 1246 #endif /* DEBUG */
1337 error = XFS_ERROR(EIN 1247 error = XFS_ERROR(EINVAL);
1338 } 1248 }
1339 error0: <<
1340 xfs_trans_brelse(tp, agbp); 1249 xfs_trans_brelse(tp, agbp);
1341 xfs_btree_del_cursor(cur, XFS 1250 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
1342 if (error) 1251 if (error)
1343 return error; 1252 return error;
1344 chunk_agbno = XFS_AGINO_TO_AG 1253 chunk_agbno = XFS_AGINO_TO_AGBNO(mp, chunk_agino);
1345 offset_agbno = agbno - chunk_ 1254 offset_agbno = agbno - chunk_agbno;
1346 } 1255 }
1347 <<
1348 ASSERT(agbno >= chunk_agbno); 1256 ASSERT(agbno >= chunk_agbno);
1349 cluster_agbno = chunk_agbno + 1257 cluster_agbno = chunk_agbno +
1350 ((offset_agbno / blks_per_clu 1258 ((offset_agbno / blks_per_cluster) * blks_per_cluster);
1351 offset = ((agbno - cluster_agbno) * m 1259 offset = ((agbno - cluster_agbno) * mp->m_sb.sb_inopblock) +
1352 XFS_INO_TO_OFFSET(mp, ino); 1260 XFS_INO_TO_OFFSET(mp, ino);
1353 !! 1261 *bno = XFS_AGB_TO_FSB(mp, agno, cluster_agbno);
1354 imap->im_blkno = XFS_AGB_TO_DADDR(mp, !! 1262 *off = offset;
1355 imap->im_len = XFS_FSB_TO_BB(mp, blks !! 1263 *len = blks_per_cluster;
1356 imap->im_boffset = (ushort)(offset << <<
1357 <<
1358 /* <<
1359 * If the inode number maps to a bloc <<
1360 * of the file system then return NUL <<
1361 * read_buf and panicing when we get <<
1362 * driver. <<
1363 */ <<
1364 if ((imap->im_blkno + imap->im_len) > <<
1365 XFS_FSB_TO_BB(mp, mp->m_sb.sb_dbl <<
1366 xfs_fs_cmn_err(CE_ALERT, mp, <<
1367 "(imap->im_blkno (0x% <<
1368 " XFS_FSB_TO_BB(mp, m <<
1369 (unsigned long long) <<
1370 (unsigned long long) <<
1371 XFS_FSB_TO_BB(mp, mp- <<
1372 return XFS_ERROR(EINVAL); <<
1373 } <<
1374 <<
1375 return 0; 1264 return 0;
>> 1265 error0:
>> 1266 xfs_trans_brelse(tp, agbp);
>> 1267 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
>> 1268 return error;
1376 } 1269 }
1377 1270
1378 /* 1271 /*
1379 * Compute and fill in value of m_in_maxlevel 1272 * Compute and fill in value of m_in_maxlevels.
1380 */ 1273 */
1381 void 1274 void
1382 xfs_ialloc_compute_maxlevels( 1275 xfs_ialloc_compute_maxlevels(
1383 xfs_mount_t *mp) /* fi 1276 xfs_mount_t *mp) /* file system mount structure */
1384 { 1277 {
1385 int level; 1278 int level;
1386 uint maxblocks; 1279 uint maxblocks;
1387 uint maxleafents; 1280 uint maxleafents;
1388 int minleafrecs; 1281 int minleafrecs;
1389 int minnoderecs; 1282 int minnoderecs;
1390 1283
1391 maxleafents = (1LL << XFS_INO_AGINO_B 1284 maxleafents = (1LL << XFS_INO_AGINO_BITS(mp)) >>
1392 XFS_INODES_PER_CHUNK_LOG; 1285 XFS_INODES_PER_CHUNK_LOG;
1393 minleafrecs = mp->m_alloc_mnr[0]; 1286 minleafrecs = mp->m_alloc_mnr[0];
1394 minnoderecs = mp->m_alloc_mnr[1]; 1287 minnoderecs = mp->m_alloc_mnr[1];
1395 maxblocks = (maxleafents + minleafrec 1288 maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
1396 for (level = 1; maxblocks > 1; level+ 1289 for (level = 1; maxblocks > 1; level++)
1397 maxblocks = (maxblocks + minn 1290 maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs;
1398 mp->m_in_maxlevels = level; 1291 mp->m_in_maxlevels = level;
1399 } 1292 }
1400 1293
1401 /* 1294 /*
1402 * Log specified fields for the ag hdr (inode 1295 * Log specified fields for the ag hdr (inode section)
1403 */ 1296 */
1404 void 1297 void
1405 xfs_ialloc_log_agi( 1298 xfs_ialloc_log_agi(
1406 xfs_trans_t *tp, /* tr 1299 xfs_trans_t *tp, /* transaction pointer */
1407 xfs_buf_t *bp, /* al 1300 xfs_buf_t *bp, /* allocation group header buffer */
1408 int fields) /* bi 1301 int fields) /* bitmask of fields to log */
1409 { 1302 {
1410 int first; 1303 int first; /* first byte number */
1411 int last; 1304 int last; /* last byte number */
1412 static const short offsets[] = { 1305 static const short offsets[] = { /* field starting offsets */
1413 /* ke 1306 /* keep in sync with bit definitions */
1414 offsetof(xfs_agi_t, agi_magic 1307 offsetof(xfs_agi_t, agi_magicnum),
1415 offsetof(xfs_agi_t, agi_versi 1308 offsetof(xfs_agi_t, agi_versionnum),
1416 offsetof(xfs_agi_t, agi_seqno 1309 offsetof(xfs_agi_t, agi_seqno),
1417 offsetof(xfs_agi_t, agi_lengt 1310 offsetof(xfs_agi_t, agi_length),
1418 offsetof(xfs_agi_t, agi_count 1311 offsetof(xfs_agi_t, agi_count),
1419 offsetof(xfs_agi_t, agi_root) 1312 offsetof(xfs_agi_t, agi_root),
1420 offsetof(xfs_agi_t, agi_level 1313 offsetof(xfs_agi_t, agi_level),
1421 offsetof(xfs_agi_t, agi_freec 1314 offsetof(xfs_agi_t, agi_freecount),
1422 offsetof(xfs_agi_t, agi_newin 1315 offsetof(xfs_agi_t, agi_newino),
1423 offsetof(xfs_agi_t, agi_dirin 1316 offsetof(xfs_agi_t, agi_dirino),
1424 offsetof(xfs_agi_t, agi_unlin 1317 offsetof(xfs_agi_t, agi_unlinked),
1425 sizeof(xfs_agi_t) 1318 sizeof(xfs_agi_t)
1426 }; 1319 };
1427 #ifdef DEBUG 1320 #ifdef DEBUG
1428 xfs_agi_t *agi; /* al 1321 xfs_agi_t *agi; /* allocation group header */
1429 1322
1430 agi = XFS_BUF_TO_AGI(bp); 1323 agi = XFS_BUF_TO_AGI(bp);
1431 ASSERT(be32_to_cpu(agi->agi_magicnum) !! 1324 ASSERT(INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC);
1432 #endif 1325 #endif
1433 /* 1326 /*
1434 * Compute byte offsets for the first 1327 * Compute byte offsets for the first and last fields.
1435 */ 1328 */
1436 xfs_btree_offsets(fields, offsets, XF 1329 xfs_btree_offsets(fields, offsets, XFS_AGI_NUM_BITS, &first, &last);
1437 /* 1330 /*
1438 * Log the allocation group inode hea 1331 * Log the allocation group inode header buffer.
1439 */ 1332 */
1440 xfs_trans_log_buf(tp, bp, first, last 1333 xfs_trans_log_buf(tp, bp, first, last);
1441 } 1334 }
1442 1335
1443 #ifdef DEBUG <<
1444 STATIC void <<
1445 xfs_check_agi_unlinked( <<
1446 struct xfs_agi *agi) <<
1447 { <<
1448 int i; <<
1449 <<
1450 for (i = 0; i < XFS_AGI_UNLINKED_BUCK <<
1451 ASSERT(agi->agi_unlinked[i]); <<
1452 } <<
1453 #else <<
1454 #define xfs_check_agi_unlinked(agi) <<
1455 #endif <<
1456 <<
1457 /* 1336 /*
1458 * Read in the allocation group header (inode 1337 * Read in the allocation group header (inode allocation section)
1459 */ 1338 */
1460 int 1339 int
1461 xfs_read_agi( !! 1340 xfs_ialloc_read_agi(
1462 struct xfs_mount *mp, /* fi !! 1341 xfs_mount_t *mp, /* file system mount structure */
1463 struct xfs_trans *tp, /* tr !! 1342 xfs_trans_t *tp, /* transaction pointer */
1464 xfs_agnumber_t agno, /* al !! 1343 xfs_agnumber_t agno, /* allocation group number */
1465 struct xfs_buf **bpp) /* al !! 1344 xfs_buf_t **bpp) /* allocation group hdr buf */
1466 { 1345 {
1467 struct xfs_agi *agi; /* al !! 1346 xfs_agi_t *agi; /* allocation group header */
1468 int agi_ok; /* ag !! 1347 int agi_ok; /* agi is consistent */
1469 int error; !! 1348 xfs_buf_t *bp; /* allocation group hdr buf */
>> 1349 xfs_perag_t *pag; /* per allocation group data */
>> 1350 int error;
1470 1351
1471 ASSERT(agno != NULLAGNUMBER); 1352 ASSERT(agno != NULLAGNUMBER);
1472 !! 1353 error = xfs_trans_read_buf(
1473 error = xfs_trans_read_buf(mp, tp, mp !! 1354 mp, tp, mp->m_ddev_targp,
1474 XFS_AG_DADDR(mp, agno 1355 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
1475 XFS_FSS_TO_BB(mp, 1), !! 1356 XFS_FSS_TO_BB(mp, 1), 0, &bp);
1476 if (error) 1357 if (error)
1477 return error; 1358 return error;
1478 !! 1359 ASSERT(bp && !XFS_BUF_GETERROR(bp));
1479 ASSERT(*bpp && !XFS_BUF_GETERROR(*bpp <<
1480 agi = XFS_BUF_TO_AGI(*bpp); <<
1481 1360
1482 /* 1361 /*
1483 * Validate the magic number of the a 1362 * Validate the magic number of the agi block.
1484 */ 1363 */
1485 agi_ok = be32_to_cpu(agi->agi_magicnu !! 1364 agi = XFS_BUF_TO_AGI(bp);
1486 XFS_AGI_GOOD_VERSION(be32_to_ !! 1365 agi_ok =
1487 be32_to_cpu(agi->agi_seqno) = !! 1366 INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC &&
>> 1367 XFS_AGI_GOOD_VERSION(
>> 1368 INT_GET(agi->agi_versionnum, ARCH_CONVERT));
1488 if (unlikely(XFS_TEST_ERROR(!agi_ok, 1369 if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
1489 XFS_RANDOM_IALLOC_REA 1370 XFS_RANDOM_IALLOC_READ_AGI))) {
1490 XFS_CORRUPTION_ERROR("xfs_rea !! 1371 XFS_CORRUPTION_ERROR("xfs_ialloc_read_agi", XFS_ERRLEVEL_LOW,
1491 mp, agi) 1372 mp, agi);
1492 xfs_trans_brelse(tp, *bpp); !! 1373 xfs_trans_brelse(tp, bp);
1493 return XFS_ERROR(EFSCORRUPTED 1374 return XFS_ERROR(EFSCORRUPTED);
1494 } 1375 }
1495 <<
1496 XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_AGI, <<
1497 <<
1498 xfs_check_agi_unlinked(agi); <<
1499 return 0; <<
1500 } <<
1501 <<
1502 int <<
1503 xfs_ialloc_read_agi( <<
1504 struct xfs_mount *mp, /* fi <<
1505 struct xfs_trans *tp, /* tr <<
1506 xfs_agnumber_t agno, /* al <<
1507 struct xfs_buf **bpp) /* al <<
1508 { <<
1509 struct xfs_agi *agi; /* al <<
1510 struct xfs_perag *pag; /* pe <<
1511 int error; <<
1512 <<
1513 error = xfs_read_agi(mp, tp, agno, bp <<
1514 if (error) <<
1515 return error; <<
1516 <<
1517 agi = XFS_BUF_TO_AGI(*bpp); <<
1518 pag = &mp->m_perag[agno]; 1376 pag = &mp->m_perag[agno];
1519 <<
1520 if (!pag->pagi_init) { 1377 if (!pag->pagi_init) {
1521 pag->pagi_freecount = be32_to !! 1378 pag->pagi_freecount = INT_GET(agi->agi_freecount, ARCH_CONVERT);
1522 pag->pagi_count = be32_to_cpu <<
1523 pag->pagi_init = 1; 1379 pag->pagi_init = 1;
>> 1380 } else {
>> 1381 /*
>> 1382 * It's possible for these to be out of sync if
>> 1383 * we are in the middle of a forced shutdown.
>> 1384 */
>> 1385 ASSERT(pag->pagi_freecount ==
>> 1386 INT_GET(agi->agi_freecount, ARCH_CONVERT)
>> 1387 || XFS_FORCED_SHUTDOWN(mp));
1524 } 1388 }
1525 1389
1526 /* !! 1390 #ifdef DEBUG
1527 * It's possible for these to be out !! 1391 {
1528 * we are in the middle of a forced s !! 1392 int i;
1529 */ <<
1530 ASSERT(pag->pagi_freecount == be32_to <<
1531 XFS_FORCED_SHUTDOWN(mp)); <<
1532 return 0; <<
1533 } <<
1534 1393
1535 /* !! 1394 for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++)
1536 * Read in the agi to initialise the per-ag d !! 1395 ASSERT(!INT_ISZERO(agi->agi_unlinked[i], ARCH_CONVERT));
1537 */ !! 1396 }
1538 int !! 1397 #endif
1539 xfs_ialloc_pagi_init( <<
1540 xfs_mount_t *mp, /* fi <<
1541 xfs_trans_t *tp, /* tr <<
1542 xfs_agnumber_t agno) /* al <<
1543 { <<
1544 xfs_buf_t *bp = NULL; <<
1545 int error; <<
1546 1398
1547 error = xfs_ialloc_read_agi(mp, tp, a !! 1399 XFS_BUF_SET_VTYPE_REF(bp, B_FS_AGI, XFS_AGI_REF);
1548 if (error) !! 1400 *bpp = bp;
1549 return error; <<
1550 if (bp) <<
1551 xfs_trans_brelse(tp, bp); <<
1552 return 0; 1401 return 0;
1553 } 1402 }
1554 1403
|
This page was automatically generated by the
LXR engine.
|