Commit 70e73f59755867383edf563d5a5cbea614c0fd49

Authored by Nathan Scott
1 parent 9cea236492

[XFS] endianess annotations for xfs_dir2_data_hdr structure.

SGI-PV: 943272
SGI-Modid: xfs-linux-melb:xfs-kern:25484a

Signed-off-by: Nathan Scott <nathans@sgi.com>

Showing 6 changed files with 99 additions and 93 deletions Inline Diff

fs/xfs/xfs_da_btree.c
1 /* 1 /*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 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 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 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, 15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18 #include "xfs.h" 18 #include "xfs.h"
19 #include "xfs_fs.h" 19 #include "xfs_fs.h"
20 #include "xfs_types.h" 20 #include "xfs_types.h"
21 #include "xfs_bit.h" 21 #include "xfs_bit.h"
22 #include "xfs_log.h" 22 #include "xfs_log.h"
23 #include "xfs_inum.h" 23 #include "xfs_inum.h"
24 #include "xfs_trans.h" 24 #include "xfs_trans.h"
25 #include "xfs_sb.h" 25 #include "xfs_sb.h"
26 #include "xfs_ag.h" 26 #include "xfs_ag.h"
27 #include "xfs_dir.h" 27 #include "xfs_dir.h"
28 #include "xfs_dir2.h" 28 #include "xfs_dir2.h"
29 #include "xfs_dmapi.h" 29 #include "xfs_dmapi.h"
30 #include "xfs_mount.h" 30 #include "xfs_mount.h"
31 #include "xfs_da_btree.h" 31 #include "xfs_da_btree.h"
32 #include "xfs_bmap_btree.h" 32 #include "xfs_bmap_btree.h"
33 #include "xfs_alloc_btree.h" 33 #include "xfs_alloc_btree.h"
34 #include "xfs_ialloc_btree.h" 34 #include "xfs_ialloc_btree.h"
35 #include "xfs_dir_sf.h" 35 #include "xfs_dir_sf.h"
36 #include "xfs_dir2_sf.h" 36 #include "xfs_dir2_sf.h"
37 #include "xfs_attr_sf.h" 37 #include "xfs_attr_sf.h"
38 #include "xfs_dinode.h" 38 #include "xfs_dinode.h"
39 #include "xfs_inode.h" 39 #include "xfs_inode.h"
40 #include "xfs_inode_item.h" 40 #include "xfs_inode_item.h"
41 #include "xfs_alloc.h" 41 #include "xfs_alloc.h"
42 #include "xfs_btree.h" 42 #include "xfs_btree.h"
43 #include "xfs_bmap.h" 43 #include "xfs_bmap.h"
44 #include "xfs_attr.h" 44 #include "xfs_attr.h"
45 #include "xfs_attr_leaf.h" 45 #include "xfs_attr_leaf.h"
46 #include "xfs_dir_leaf.h" 46 #include "xfs_dir_leaf.h"
47 #include "xfs_dir2_data.h" 47 #include "xfs_dir2_data.h"
48 #include "xfs_dir2_leaf.h" 48 #include "xfs_dir2_leaf.h"
49 #include "xfs_dir2_block.h" 49 #include "xfs_dir2_block.h"
50 #include "xfs_dir2_node.h" 50 #include "xfs_dir2_node.h"
51 #include "xfs_error.h" 51 #include "xfs_error.h"
52 52
53 /* 53 /*
54 * xfs_da_btree.c 54 * xfs_da_btree.c
55 * 55 *
56 * Routines to implement directories as Btrees of hashed names. 56 * Routines to implement directories as Btrees of hashed names.
57 */ 57 */
58 58
59 /*======================================================================== 59 /*========================================================================
60 * Function prototypes for the kernel. 60 * Function prototypes for the kernel.
61 *========================================================================*/ 61 *========================================================================*/
62 62
63 /* 63 /*
64 * Routines used for growing the Btree. 64 * Routines used for growing the Btree.
65 */ 65 */
66 STATIC int xfs_da_root_split(xfs_da_state_t *state, 66 STATIC int xfs_da_root_split(xfs_da_state_t *state,
67 xfs_da_state_blk_t *existing_root, 67 xfs_da_state_blk_t *existing_root,
68 xfs_da_state_blk_t *new_child); 68 xfs_da_state_blk_t *new_child);
69 STATIC int xfs_da_node_split(xfs_da_state_t *state, 69 STATIC int xfs_da_node_split(xfs_da_state_t *state,
70 xfs_da_state_blk_t *existing_blk, 70 xfs_da_state_blk_t *existing_blk,
71 xfs_da_state_blk_t *split_blk, 71 xfs_da_state_blk_t *split_blk,
72 xfs_da_state_blk_t *blk_to_add, 72 xfs_da_state_blk_t *blk_to_add,
73 int treelevel, 73 int treelevel,
74 int *result); 74 int *result);
75 STATIC void xfs_da_node_rebalance(xfs_da_state_t *state, 75 STATIC void xfs_da_node_rebalance(xfs_da_state_t *state,
76 xfs_da_state_blk_t *node_blk_1, 76 xfs_da_state_blk_t *node_blk_1,
77 xfs_da_state_blk_t *node_blk_2); 77 xfs_da_state_blk_t *node_blk_2);
78 STATIC void xfs_da_node_add(xfs_da_state_t *state, 78 STATIC void xfs_da_node_add(xfs_da_state_t *state,
79 xfs_da_state_blk_t *old_node_blk, 79 xfs_da_state_blk_t *old_node_blk,
80 xfs_da_state_blk_t *new_node_blk); 80 xfs_da_state_blk_t *new_node_blk);
81 81
82 /* 82 /*
83 * Routines used for shrinking the Btree. 83 * Routines used for shrinking the Btree.
84 */ 84 */
85 STATIC int xfs_da_root_join(xfs_da_state_t *state, 85 STATIC int xfs_da_root_join(xfs_da_state_t *state,
86 xfs_da_state_blk_t *root_blk); 86 xfs_da_state_blk_t *root_blk);
87 STATIC int xfs_da_node_toosmall(xfs_da_state_t *state, int *retval); 87 STATIC int xfs_da_node_toosmall(xfs_da_state_t *state, int *retval);
88 STATIC void xfs_da_node_remove(xfs_da_state_t *state, 88 STATIC void xfs_da_node_remove(xfs_da_state_t *state,
89 xfs_da_state_blk_t *drop_blk); 89 xfs_da_state_blk_t *drop_blk);
90 STATIC void xfs_da_node_unbalance(xfs_da_state_t *state, 90 STATIC void xfs_da_node_unbalance(xfs_da_state_t *state,
91 xfs_da_state_blk_t *src_node_blk, 91 xfs_da_state_blk_t *src_node_blk,
92 xfs_da_state_blk_t *dst_node_blk); 92 xfs_da_state_blk_t *dst_node_blk);
93 93
94 /* 94 /*
95 * Utility routines. 95 * Utility routines.
96 */ 96 */
97 STATIC uint xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count); 97 STATIC uint xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count);
98 STATIC int xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp); 98 STATIC int xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp);
99 STATIC xfs_dabuf_t *xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra); 99 STATIC xfs_dabuf_t *xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra);
100 STATIC int xfs_da_blk_unlink(xfs_da_state_t *state, 100 STATIC int xfs_da_blk_unlink(xfs_da_state_t *state,
101 xfs_da_state_blk_t *drop_blk, 101 xfs_da_state_blk_t *drop_blk,
102 xfs_da_state_blk_t *save_blk); 102 xfs_da_state_blk_t *save_blk);
103 STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state); 103 STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state);
104 104
105 /*======================================================================== 105 /*========================================================================
106 * Routines used for growing the Btree. 106 * Routines used for growing the Btree.
107 *========================================================================*/ 107 *========================================================================*/
108 108
109 /* 109 /*
110 * Create the initial contents of an intermediate node. 110 * Create the initial contents of an intermediate node.
111 */ 111 */
112 int 112 int
113 xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level, 113 xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level,
114 xfs_dabuf_t **bpp, int whichfork) 114 xfs_dabuf_t **bpp, int whichfork)
115 { 115 {
116 xfs_da_intnode_t *node; 116 xfs_da_intnode_t *node;
117 xfs_dabuf_t *bp; 117 xfs_dabuf_t *bp;
118 int error; 118 int error;
119 xfs_trans_t *tp; 119 xfs_trans_t *tp;
120 120
121 tp = args->trans; 121 tp = args->trans;
122 error = xfs_da_get_buf(tp, args->dp, blkno, -1, &bp, whichfork); 122 error = xfs_da_get_buf(tp, args->dp, blkno, -1, &bp, whichfork);
123 if (error) 123 if (error)
124 return(error); 124 return(error);
125 ASSERT(bp != NULL); 125 ASSERT(bp != NULL);
126 node = bp->data; 126 node = bp->data;
127 node->hdr.info.forw = 0; 127 node->hdr.info.forw = 0;
128 node->hdr.info.back = 0; 128 node->hdr.info.back = 0;
129 INT_SET(node->hdr.info.magic, ARCH_CONVERT, XFS_DA_NODE_MAGIC); 129 INT_SET(node->hdr.info.magic, ARCH_CONVERT, XFS_DA_NODE_MAGIC);
130 node->hdr.info.pad = 0; 130 node->hdr.info.pad = 0;
131 node->hdr.count = 0; 131 node->hdr.count = 0;
132 INT_SET(node->hdr.level, ARCH_CONVERT, level); 132 INT_SET(node->hdr.level, ARCH_CONVERT, level);
133 133
134 xfs_da_log_buf(tp, bp, 134 xfs_da_log_buf(tp, bp,
135 XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); 135 XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr)));
136 136
137 *bpp = bp; 137 *bpp = bp;
138 return(0); 138 return(0);
139 } 139 }
140 140
141 /* 141 /*
142 * Split a leaf node, rebalance, then possibly split 142 * Split a leaf node, rebalance, then possibly split
143 * intermediate nodes, rebalance, etc. 143 * intermediate nodes, rebalance, etc.
144 */ 144 */
145 int /* error */ 145 int /* error */
146 xfs_da_split(xfs_da_state_t *state) 146 xfs_da_split(xfs_da_state_t *state)
147 { 147 {
148 xfs_da_state_blk_t *oldblk, *newblk, *addblk; 148 xfs_da_state_blk_t *oldblk, *newblk, *addblk;
149 xfs_da_intnode_t *node; 149 xfs_da_intnode_t *node;
150 xfs_dabuf_t *bp; 150 xfs_dabuf_t *bp;
151 int max, action, error, i; 151 int max, action, error, i;
152 152
153 /* 153 /*
154 * Walk back up the tree splitting/inserting/adjusting as necessary. 154 * Walk back up the tree splitting/inserting/adjusting as necessary.
155 * If we need to insert and there isn't room, split the node, then 155 * If we need to insert and there isn't room, split the node, then
156 * decide which fragment to insert the new block from below into. 156 * decide which fragment to insert the new block from below into.
157 * Note that we may split the root this way, but we need more fixup. 157 * Note that we may split the root this way, but we need more fixup.
158 */ 158 */
159 max = state->path.active - 1; 159 max = state->path.active - 1;
160 ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH)); 160 ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH));
161 ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC || 161 ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC ||
162 state->path.blk[max].magic == XFS_DIRX_LEAF_MAGIC(state->mp)); 162 state->path.blk[max].magic == XFS_DIRX_LEAF_MAGIC(state->mp));
163 163
164 addblk = &state->path.blk[max]; /* initial dummy value */ 164 addblk = &state->path.blk[max]; /* initial dummy value */
165 for (i = max; (i >= 0) && addblk; state->path.active--, i--) { 165 for (i = max; (i >= 0) && addblk; state->path.active--, i--) {
166 oldblk = &state->path.blk[i]; 166 oldblk = &state->path.blk[i];
167 newblk = &state->altpath.blk[i]; 167 newblk = &state->altpath.blk[i];
168 168
169 /* 169 /*
170 * If a leaf node then 170 * If a leaf node then
171 * Allocate a new leaf node, then rebalance across them. 171 * Allocate a new leaf node, then rebalance across them.
172 * else if an intermediate node then 172 * else if an intermediate node then
173 * We split on the last layer, must we split the node? 173 * We split on the last layer, must we split the node?
174 */ 174 */
175 switch (oldblk->magic) { 175 switch (oldblk->magic) {
176 case XFS_ATTR_LEAF_MAGIC: 176 case XFS_ATTR_LEAF_MAGIC:
177 error = xfs_attr_leaf_split(state, oldblk, newblk); 177 error = xfs_attr_leaf_split(state, oldblk, newblk);
178 if ((error != 0) && (error != ENOSPC)) { 178 if ((error != 0) && (error != ENOSPC)) {
179 return(error); /* GROT: attr is inconsistent */ 179 return(error); /* GROT: attr is inconsistent */
180 } 180 }
181 if (!error) { 181 if (!error) {
182 addblk = newblk; 182 addblk = newblk;
183 break; 183 break;
184 } 184 }
185 /* 185 /*
186 * Entry wouldn't fit, split the leaf again. 186 * Entry wouldn't fit, split the leaf again.
187 */ 187 */
188 state->extravalid = 1; 188 state->extravalid = 1;
189 if (state->inleaf) { 189 if (state->inleaf) {
190 state->extraafter = 0; /* before newblk */ 190 state->extraafter = 0; /* before newblk */
191 error = xfs_attr_leaf_split(state, oldblk, 191 error = xfs_attr_leaf_split(state, oldblk,
192 &state->extrablk); 192 &state->extrablk);
193 } else { 193 } else {
194 state->extraafter = 1; /* after newblk */ 194 state->extraafter = 1; /* after newblk */
195 error = xfs_attr_leaf_split(state, newblk, 195 error = xfs_attr_leaf_split(state, newblk,
196 &state->extrablk); 196 &state->extrablk);
197 } 197 }
198 if (error) 198 if (error)
199 return(error); /* GROT: attr inconsistent */ 199 return(error); /* GROT: attr inconsistent */
200 addblk = newblk; 200 addblk = newblk;
201 break; 201 break;
202 case XFS_DIR_LEAF_MAGIC: 202 case XFS_DIR_LEAF_MAGIC:
203 ASSERT(XFS_DIR_IS_V1(state->mp)); 203 ASSERT(XFS_DIR_IS_V1(state->mp));
204 error = xfs_dir_leaf_split(state, oldblk, newblk); 204 error = xfs_dir_leaf_split(state, oldblk, newblk);
205 if ((error != 0) && (error != ENOSPC)) { 205 if ((error != 0) && (error != ENOSPC)) {
206 return(error); /* GROT: dir is inconsistent */ 206 return(error); /* GROT: dir is inconsistent */
207 } 207 }
208 if (!error) { 208 if (!error) {
209 addblk = newblk; 209 addblk = newblk;
210 break; 210 break;
211 } 211 }
212 /* 212 /*
213 * Entry wouldn't fit, split the leaf again. 213 * Entry wouldn't fit, split the leaf again.
214 */ 214 */
215 state->extravalid = 1; 215 state->extravalid = 1;
216 if (state->inleaf) { 216 if (state->inleaf) {
217 state->extraafter = 0; /* before newblk */ 217 state->extraafter = 0; /* before newblk */
218 error = xfs_dir_leaf_split(state, oldblk, 218 error = xfs_dir_leaf_split(state, oldblk,
219 &state->extrablk); 219 &state->extrablk);
220 if (error) 220 if (error)
221 return(error); /* GROT: dir incon. */ 221 return(error); /* GROT: dir incon. */
222 addblk = newblk; 222 addblk = newblk;
223 } else { 223 } else {
224 state->extraafter = 1; /* after newblk */ 224 state->extraafter = 1; /* after newblk */
225 error = xfs_dir_leaf_split(state, newblk, 225 error = xfs_dir_leaf_split(state, newblk,
226 &state->extrablk); 226 &state->extrablk);
227 if (error) 227 if (error)
228 return(error); /* GROT: dir incon. */ 228 return(error); /* GROT: dir incon. */
229 addblk = newblk; 229 addblk = newblk;
230 } 230 }
231 break; 231 break;
232 case XFS_DIR2_LEAFN_MAGIC: 232 case XFS_DIR2_LEAFN_MAGIC:
233 ASSERT(XFS_DIR_IS_V2(state->mp)); 233 ASSERT(XFS_DIR_IS_V2(state->mp));
234 error = xfs_dir2_leafn_split(state, oldblk, newblk); 234 error = xfs_dir2_leafn_split(state, oldblk, newblk);
235 if (error) 235 if (error)
236 return error; 236 return error;
237 addblk = newblk; 237 addblk = newblk;
238 break; 238 break;
239 case XFS_DA_NODE_MAGIC: 239 case XFS_DA_NODE_MAGIC:
240 error = xfs_da_node_split(state, oldblk, newblk, addblk, 240 error = xfs_da_node_split(state, oldblk, newblk, addblk,
241 max - i, &action); 241 max - i, &action);
242 xfs_da_buf_done(addblk->bp); 242 xfs_da_buf_done(addblk->bp);
243 addblk->bp = NULL; 243 addblk->bp = NULL;
244 if (error) 244 if (error)
245 return(error); /* GROT: dir is inconsistent */ 245 return(error); /* GROT: dir is inconsistent */
246 /* 246 /*
247 * Record the newly split block for the next time thru? 247 * Record the newly split block for the next time thru?
248 */ 248 */
249 if (action) 249 if (action)
250 addblk = newblk; 250 addblk = newblk;
251 else 251 else
252 addblk = NULL; 252 addblk = NULL;
253 break; 253 break;
254 } 254 }
255 255
256 /* 256 /*
257 * Update the btree to show the new hashval for this child. 257 * Update the btree to show the new hashval for this child.
258 */ 258 */
259 xfs_da_fixhashpath(state, &state->path); 259 xfs_da_fixhashpath(state, &state->path);
260 /* 260 /*
261 * If we won't need this block again, it's getting dropped 261 * If we won't need this block again, it's getting dropped
262 * from the active path by the loop control, so we need 262 * from the active path by the loop control, so we need
263 * to mark it done now. 263 * to mark it done now.
264 */ 264 */
265 if (i > 0 || !addblk) 265 if (i > 0 || !addblk)
266 xfs_da_buf_done(oldblk->bp); 266 xfs_da_buf_done(oldblk->bp);
267 } 267 }
268 if (!addblk) 268 if (!addblk)
269 return(0); 269 return(0);
270 270
271 /* 271 /*
272 * Split the root node. 272 * Split the root node.
273 */ 273 */
274 ASSERT(state->path.active == 0); 274 ASSERT(state->path.active == 0);
275 oldblk = &state->path.blk[0]; 275 oldblk = &state->path.blk[0];
276 error = xfs_da_root_split(state, oldblk, addblk); 276 error = xfs_da_root_split(state, oldblk, addblk);
277 if (error) { 277 if (error) {
278 xfs_da_buf_done(oldblk->bp); 278 xfs_da_buf_done(oldblk->bp);
279 xfs_da_buf_done(addblk->bp); 279 xfs_da_buf_done(addblk->bp);
280 addblk->bp = NULL; 280 addblk->bp = NULL;
281 return(error); /* GROT: dir is inconsistent */ 281 return(error); /* GROT: dir is inconsistent */
282 } 282 }
283 283
284 /* 284 /*
285 * Update pointers to the node which used to be block 0 and 285 * Update pointers to the node which used to be block 0 and
286 * just got bumped because of the addition of a new root node. 286 * just got bumped because of the addition of a new root node.
287 * There might be three blocks involved if a double split occurred, 287 * There might be three blocks involved if a double split occurred,
288 * and the original block 0 could be at any position in the list. 288 * and the original block 0 could be at any position in the list.
289 */ 289 */
290 290
291 node = oldblk->bp->data; 291 node = oldblk->bp->data;
292 if (node->hdr.info.forw) { 292 if (node->hdr.info.forw) {
293 if (INT_GET(node->hdr.info.forw, ARCH_CONVERT) == addblk->blkno) { 293 if (INT_GET(node->hdr.info.forw, ARCH_CONVERT) == addblk->blkno) {
294 bp = addblk->bp; 294 bp = addblk->bp;
295 } else { 295 } else {
296 ASSERT(state->extravalid); 296 ASSERT(state->extravalid);
297 bp = state->extrablk.bp; 297 bp = state->extrablk.bp;
298 } 298 }
299 node = bp->data; 299 node = bp->data;
300 INT_SET(node->hdr.info.back, ARCH_CONVERT, oldblk->blkno); 300 INT_SET(node->hdr.info.back, ARCH_CONVERT, oldblk->blkno);
301 xfs_da_log_buf(state->args->trans, bp, 301 xfs_da_log_buf(state->args->trans, bp,
302 XFS_DA_LOGRANGE(node, &node->hdr.info, 302 XFS_DA_LOGRANGE(node, &node->hdr.info,
303 sizeof(node->hdr.info))); 303 sizeof(node->hdr.info)));
304 } 304 }
305 node = oldblk->bp->data; 305 node = oldblk->bp->data;
306 if (INT_GET(node->hdr.info.back, ARCH_CONVERT)) { 306 if (INT_GET(node->hdr.info.back, ARCH_CONVERT)) {
307 if (INT_GET(node->hdr.info.back, ARCH_CONVERT) == addblk->blkno) { 307 if (INT_GET(node->hdr.info.back, ARCH_CONVERT) == addblk->blkno) {
308 bp = addblk->bp; 308 bp = addblk->bp;
309 } else { 309 } else {
310 ASSERT(state->extravalid); 310 ASSERT(state->extravalid);
311 bp = state->extrablk.bp; 311 bp = state->extrablk.bp;
312 } 312 }
313 node = bp->data; 313 node = bp->data;
314 INT_SET(node->hdr.info.forw, ARCH_CONVERT, oldblk->blkno); 314 INT_SET(node->hdr.info.forw, ARCH_CONVERT, oldblk->blkno);
315 xfs_da_log_buf(state->args->trans, bp, 315 xfs_da_log_buf(state->args->trans, bp,
316 XFS_DA_LOGRANGE(node, &node->hdr.info, 316 XFS_DA_LOGRANGE(node, &node->hdr.info,
317 sizeof(node->hdr.info))); 317 sizeof(node->hdr.info)));
318 } 318 }
319 xfs_da_buf_done(oldblk->bp); 319 xfs_da_buf_done(oldblk->bp);
320 xfs_da_buf_done(addblk->bp); 320 xfs_da_buf_done(addblk->bp);
321 addblk->bp = NULL; 321 addblk->bp = NULL;
322 return(0); 322 return(0);
323 } 323 }
324 324
325 /* 325 /*
326 * Split the root. We have to create a new root and point to the two 326 * Split the root. We have to create a new root and point to the two
327 * parts (the split old root) that we just created. Copy block zero to 327 * parts (the split old root) that we just created. Copy block zero to
328 * the EOF, extending the inode in process. 328 * the EOF, extending the inode in process.
329 */ 329 */
330 STATIC int /* error */ 330 STATIC int /* error */
331 xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, 331 xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
332 xfs_da_state_blk_t *blk2) 332 xfs_da_state_blk_t *blk2)
333 { 333 {
334 xfs_da_intnode_t *node, *oldroot; 334 xfs_da_intnode_t *node, *oldroot;
335 xfs_da_args_t *args; 335 xfs_da_args_t *args;
336 xfs_dablk_t blkno; 336 xfs_dablk_t blkno;
337 xfs_dabuf_t *bp; 337 xfs_dabuf_t *bp;
338 int error, size; 338 int error, size;
339 xfs_inode_t *dp; 339 xfs_inode_t *dp;
340 xfs_trans_t *tp; 340 xfs_trans_t *tp;
341 xfs_mount_t *mp; 341 xfs_mount_t *mp;
342 xfs_dir2_leaf_t *leaf; 342 xfs_dir2_leaf_t *leaf;
343 343
344 /* 344 /*
345 * Copy the existing (incorrect) block from the root node position 345 * Copy the existing (incorrect) block from the root node position
346 * to a free space somewhere. 346 * to a free space somewhere.
347 */ 347 */
348 args = state->args; 348 args = state->args;
349 ASSERT(args != NULL); 349 ASSERT(args != NULL);
350 error = xfs_da_grow_inode(args, &blkno); 350 error = xfs_da_grow_inode(args, &blkno);
351 if (error) 351 if (error)
352 return(error); 352 return(error);
353 dp = args->dp; 353 dp = args->dp;
354 tp = args->trans; 354 tp = args->trans;
355 mp = state->mp; 355 mp = state->mp;
356 error = xfs_da_get_buf(tp, dp, blkno, -1, &bp, args->whichfork); 356 error = xfs_da_get_buf(tp, dp, blkno, -1, &bp, args->whichfork);
357 if (error) 357 if (error)
358 return(error); 358 return(error);
359 ASSERT(bp != NULL); 359 ASSERT(bp != NULL);
360 node = bp->data; 360 node = bp->data;
361 oldroot = blk1->bp->data; 361 oldroot = blk1->bp->data;
362 if (INT_GET(oldroot->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC) { 362 if (INT_GET(oldroot->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC) {
363 size = (int)((char *)&oldroot->btree[INT_GET(oldroot->hdr.count, ARCH_CONVERT)] - 363 size = (int)((char *)&oldroot->btree[INT_GET(oldroot->hdr.count, ARCH_CONVERT)] -
364 (char *)oldroot); 364 (char *)oldroot);
365 } else { 365 } else {
366 ASSERT(XFS_DIR_IS_V2(mp)); 366 ASSERT(XFS_DIR_IS_V2(mp));
367 ASSERT(INT_GET(oldroot->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); 367 ASSERT(INT_GET(oldroot->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
368 leaf = (xfs_dir2_leaf_t *)oldroot; 368 leaf = (xfs_dir2_leaf_t *)oldroot;
369 size = (int)((char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] - 369 size = (int)((char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] -
370 (char *)leaf); 370 (char *)leaf);
371 } 371 }
372 memcpy(node, oldroot, size); 372 memcpy(node, oldroot, size);
373 xfs_da_log_buf(tp, bp, 0, size - 1); 373 xfs_da_log_buf(tp, bp, 0, size - 1);
374 xfs_da_buf_done(blk1->bp); 374 xfs_da_buf_done(blk1->bp);
375 blk1->bp = bp; 375 blk1->bp = bp;
376 blk1->blkno = blkno; 376 blk1->blkno = blkno;
377 377
378 /* 378 /*
379 * Set up the new root node. 379 * Set up the new root node.
380 */ 380 */
381 error = xfs_da_node_create(args, 381 error = xfs_da_node_create(args,
382 args->whichfork == XFS_DATA_FORK && 382 args->whichfork == XFS_DATA_FORK &&
383 XFS_DIR_IS_V2(mp) ? mp->m_dirleafblk : 0, 383 XFS_DIR_IS_V2(mp) ? mp->m_dirleafblk : 0,
384 INT_GET(node->hdr.level, ARCH_CONVERT) + 1, &bp, args->whichfork); 384 INT_GET(node->hdr.level, ARCH_CONVERT) + 1, &bp, args->whichfork);
385 if (error) 385 if (error)
386 return(error); 386 return(error);
387 node = bp->data; 387 node = bp->data;
388 INT_SET(node->btree[0].hashval, ARCH_CONVERT, blk1->hashval); 388 INT_SET(node->btree[0].hashval, ARCH_CONVERT, blk1->hashval);
389 INT_SET(node->btree[0].before, ARCH_CONVERT, blk1->blkno); 389 INT_SET(node->btree[0].before, ARCH_CONVERT, blk1->blkno);
390 INT_SET(node->btree[1].hashval, ARCH_CONVERT, blk2->hashval); 390 INT_SET(node->btree[1].hashval, ARCH_CONVERT, blk2->hashval);
391 INT_SET(node->btree[1].before, ARCH_CONVERT, blk2->blkno); 391 INT_SET(node->btree[1].before, ARCH_CONVERT, blk2->blkno);
392 INT_SET(node->hdr.count, ARCH_CONVERT, 2); 392 INT_SET(node->hdr.count, ARCH_CONVERT, 2);
393 393
394 #ifdef DEBUG 394 #ifdef DEBUG
395 if (INT_GET(oldroot->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC) { 395 if (INT_GET(oldroot->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC) {
396 ASSERT(blk1->blkno >= mp->m_dirleafblk && 396 ASSERT(blk1->blkno >= mp->m_dirleafblk &&
397 blk1->blkno < mp->m_dirfreeblk); 397 blk1->blkno < mp->m_dirfreeblk);
398 ASSERT(blk2->blkno >= mp->m_dirleafblk && 398 ASSERT(blk2->blkno >= mp->m_dirleafblk &&
399 blk2->blkno < mp->m_dirfreeblk); 399 blk2->blkno < mp->m_dirfreeblk);
400 } 400 }
401 #endif 401 #endif
402 402
403 /* Header is already logged by xfs_da_node_create */ 403 /* Header is already logged by xfs_da_node_create */
404 xfs_da_log_buf(tp, bp, 404 xfs_da_log_buf(tp, bp,
405 XFS_DA_LOGRANGE(node, node->btree, 405 XFS_DA_LOGRANGE(node, node->btree,
406 sizeof(xfs_da_node_entry_t) * 2)); 406 sizeof(xfs_da_node_entry_t) * 2));
407 xfs_da_buf_done(bp); 407 xfs_da_buf_done(bp);
408 408
409 return(0); 409 return(0);
410 } 410 }
411 411
412 /* 412 /*
413 * Split the node, rebalance, then add the new entry. 413 * Split the node, rebalance, then add the new entry.
414 */ 414 */
415 STATIC int /* error */ 415 STATIC int /* error */
416 xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, 416 xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
417 xfs_da_state_blk_t *newblk, 417 xfs_da_state_blk_t *newblk,
418 xfs_da_state_blk_t *addblk, 418 xfs_da_state_blk_t *addblk,
419 int treelevel, int *result) 419 int treelevel, int *result)
420 { 420 {
421 xfs_da_intnode_t *node; 421 xfs_da_intnode_t *node;
422 xfs_dablk_t blkno; 422 xfs_dablk_t blkno;
423 int newcount, error; 423 int newcount, error;
424 int useextra; 424 int useextra;
425 425
426 node = oldblk->bp->data; 426 node = oldblk->bp->data;
427 ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); 427 ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
428 428
429 /* 429 /*
430 * With V2 the extra block is data or freespace. 430 * With V2 the extra block is data or freespace.
431 */ 431 */
432 useextra = state->extravalid && (XFS_DIR_IS_V1(state->mp) || 432 useextra = state->extravalid && (XFS_DIR_IS_V1(state->mp) ||
433 state->args->whichfork == XFS_ATTR_FORK); 433 state->args->whichfork == XFS_ATTR_FORK);
434 newcount = 1 + useextra; 434 newcount = 1 + useextra;
435 /* 435 /*
436 * Do we have to split the node? 436 * Do we have to split the node?
437 */ 437 */
438 if ((INT_GET(node->hdr.count, ARCH_CONVERT) + newcount) > state->node_ents) { 438 if ((INT_GET(node->hdr.count, ARCH_CONVERT) + newcount) > state->node_ents) {
439 /* 439 /*
440 * Allocate a new node, add to the doubly linked chain of 440 * Allocate a new node, add to the doubly linked chain of
441 * nodes, then move some of our excess entries into it. 441 * nodes, then move some of our excess entries into it.
442 */ 442 */
443 error = xfs_da_grow_inode(state->args, &blkno); 443 error = xfs_da_grow_inode(state->args, &blkno);
444 if (error) 444 if (error)
445 return(error); /* GROT: dir is inconsistent */ 445 return(error); /* GROT: dir is inconsistent */
446 446
447 error = xfs_da_node_create(state->args, blkno, treelevel, 447 error = xfs_da_node_create(state->args, blkno, treelevel,
448 &newblk->bp, state->args->whichfork); 448 &newblk->bp, state->args->whichfork);
449 if (error) 449 if (error)
450 return(error); /* GROT: dir is inconsistent */ 450 return(error); /* GROT: dir is inconsistent */
451 newblk->blkno = blkno; 451 newblk->blkno = blkno;
452 newblk->magic = XFS_DA_NODE_MAGIC; 452 newblk->magic = XFS_DA_NODE_MAGIC;
453 xfs_da_node_rebalance(state, oldblk, newblk); 453 xfs_da_node_rebalance(state, oldblk, newblk);
454 error = xfs_da_blk_link(state, oldblk, newblk); 454 error = xfs_da_blk_link(state, oldblk, newblk);
455 if (error) 455 if (error)
456 return(error); 456 return(error);
457 *result = 1; 457 *result = 1;
458 } else { 458 } else {
459 *result = 0; 459 *result = 0;
460 } 460 }
461 461
462 /* 462 /*
463 * Insert the new entry(s) into the correct block 463 * Insert the new entry(s) into the correct block
464 * (updating last hashval in the process). 464 * (updating last hashval in the process).
465 * 465 *
466 * xfs_da_node_add() inserts BEFORE the given index, 466 * xfs_da_node_add() inserts BEFORE the given index,
467 * and as a result of using node_lookup_int() we always 467 * and as a result of using node_lookup_int() we always
468 * point to a valid entry (not after one), but a split 468 * point to a valid entry (not after one), but a split
469 * operation always results in a new block whose hashvals 469 * operation always results in a new block whose hashvals
470 * FOLLOW the current block. 470 * FOLLOW the current block.
471 * 471 *
472 * If we had double-split op below us, then add the extra block too. 472 * If we had double-split op below us, then add the extra block too.
473 */ 473 */
474 node = oldblk->bp->data; 474 node = oldblk->bp->data;
475 if (oldblk->index <= INT_GET(node->hdr.count, ARCH_CONVERT)) { 475 if (oldblk->index <= INT_GET(node->hdr.count, ARCH_CONVERT)) {
476 oldblk->index++; 476 oldblk->index++;
477 xfs_da_node_add(state, oldblk, addblk); 477 xfs_da_node_add(state, oldblk, addblk);
478 if (useextra) { 478 if (useextra) {
479 if (state->extraafter) 479 if (state->extraafter)
480 oldblk->index++; 480 oldblk->index++;
481 xfs_da_node_add(state, oldblk, &state->extrablk); 481 xfs_da_node_add(state, oldblk, &state->extrablk);
482 state->extravalid = 0; 482 state->extravalid = 0;
483 } 483 }
484 } else { 484 } else {
485 newblk->index++; 485 newblk->index++;
486 xfs_da_node_add(state, newblk, addblk); 486 xfs_da_node_add(state, newblk, addblk);
487 if (useextra) { 487 if (useextra) {
488 if (state->extraafter) 488 if (state->extraafter)
489 newblk->index++; 489 newblk->index++;
490 xfs_da_node_add(state, newblk, &state->extrablk); 490 xfs_da_node_add(state, newblk, &state->extrablk);
491 state->extravalid = 0; 491 state->extravalid = 0;
492 } 492 }
493 } 493 }
494 494
495 return(0); 495 return(0);
496 } 496 }
497 497
498 /* 498 /*
499 * Balance the btree elements between two intermediate nodes, 499 * Balance the btree elements between two intermediate nodes,
500 * usually one full and one empty. 500 * usually one full and one empty.
501 * 501 *
502 * NOTE: if blk2 is empty, then it will get the upper half of blk1. 502 * NOTE: if blk2 is empty, then it will get the upper half of blk1.
503 */ 503 */
504 STATIC void 504 STATIC void
505 xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, 505 xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
506 xfs_da_state_blk_t *blk2) 506 xfs_da_state_blk_t *blk2)
507 { 507 {
508 xfs_da_intnode_t *node1, *node2, *tmpnode; 508 xfs_da_intnode_t *node1, *node2, *tmpnode;
509 xfs_da_node_entry_t *btree_s, *btree_d; 509 xfs_da_node_entry_t *btree_s, *btree_d;
510 int count, tmp; 510 int count, tmp;
511 xfs_trans_t *tp; 511 xfs_trans_t *tp;
512 512
513 node1 = blk1->bp->data; 513 node1 = blk1->bp->data;
514 node2 = blk2->bp->data; 514 node2 = blk2->bp->data;
515 /* 515 /*
516 * Figure out how many entries need to move, and in which direction. 516 * Figure out how many entries need to move, and in which direction.
517 * Swap the nodes around if that makes it simpler. 517 * Swap the nodes around if that makes it simpler.
518 */ 518 */
519 if ((INT_GET(node1->hdr.count, ARCH_CONVERT) > 0) && (INT_GET(node2->hdr.count, ARCH_CONVERT) > 0) && 519 if ((INT_GET(node1->hdr.count, ARCH_CONVERT) > 0) && (INT_GET(node2->hdr.count, ARCH_CONVERT) > 0) &&
520 ((INT_GET(node2->btree[ 0 ].hashval, ARCH_CONVERT) < INT_GET(node1->btree[ 0 ].hashval, ARCH_CONVERT)) || 520 ((INT_GET(node2->btree[ 0 ].hashval, ARCH_CONVERT) < INT_GET(node1->btree[ 0 ].hashval, ARCH_CONVERT)) ||
521 (INT_GET(node2->btree[ INT_GET(node2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT) < 521 (INT_GET(node2->btree[ INT_GET(node2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT) <
522 INT_GET(node1->btree[ INT_GET(node1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)))) { 522 INT_GET(node1->btree[ INT_GET(node1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)))) {
523 tmpnode = node1; 523 tmpnode = node1;
524 node1 = node2; 524 node1 = node2;
525 node2 = tmpnode; 525 node2 = tmpnode;
526 } 526 }
527 ASSERT(INT_GET(node1->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); 527 ASSERT(INT_GET(node1->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
528 ASSERT(INT_GET(node2->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); 528 ASSERT(INT_GET(node2->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
529 count = (INT_GET(node1->hdr.count, ARCH_CONVERT) - INT_GET(node2->hdr.count, ARCH_CONVERT)) / 2; 529 count = (INT_GET(node1->hdr.count, ARCH_CONVERT) - INT_GET(node2->hdr.count, ARCH_CONVERT)) / 2;
530 if (count == 0) 530 if (count == 0)
531 return; 531 return;
532 tp = state->args->trans; 532 tp = state->args->trans;
533 /* 533 /*
534 * Two cases: high-to-low and low-to-high. 534 * Two cases: high-to-low and low-to-high.
535 */ 535 */
536 if (count > 0) { 536 if (count > 0) {
537 /* 537 /*
538 * Move elements in node2 up to make a hole. 538 * Move elements in node2 up to make a hole.
539 */ 539 */
540 if ((tmp = INT_GET(node2->hdr.count, ARCH_CONVERT)) > 0) { 540 if ((tmp = INT_GET(node2->hdr.count, ARCH_CONVERT)) > 0) {
541 tmp *= (uint)sizeof(xfs_da_node_entry_t); 541 tmp *= (uint)sizeof(xfs_da_node_entry_t);
542 btree_s = &node2->btree[0]; 542 btree_s = &node2->btree[0];
543 btree_d = &node2->btree[count]; 543 btree_d = &node2->btree[count];
544 memmove(btree_d, btree_s, tmp); 544 memmove(btree_d, btree_s, tmp);
545 } 545 }
546 546
547 /* 547 /*
548 * Move the req'd B-tree elements from high in node1 to 548 * Move the req'd B-tree elements from high in node1 to
549 * low in node2. 549 * low in node2.
550 */ 550 */
551 INT_MOD(node2->hdr.count, ARCH_CONVERT, count); 551 INT_MOD(node2->hdr.count, ARCH_CONVERT, count);
552 tmp = count * (uint)sizeof(xfs_da_node_entry_t); 552 tmp = count * (uint)sizeof(xfs_da_node_entry_t);
553 btree_s = &node1->btree[INT_GET(node1->hdr.count, ARCH_CONVERT) - count]; 553 btree_s = &node1->btree[INT_GET(node1->hdr.count, ARCH_CONVERT) - count];
554 btree_d = &node2->btree[0]; 554 btree_d = &node2->btree[0];
555 memcpy(btree_d, btree_s, tmp); 555 memcpy(btree_d, btree_s, tmp);
556 INT_MOD(node1->hdr.count, ARCH_CONVERT, -(count)); 556 INT_MOD(node1->hdr.count, ARCH_CONVERT, -(count));
557 557
558 } else { 558 } else {
559 /* 559 /*
560 * Move the req'd B-tree elements from low in node2 to 560 * Move the req'd B-tree elements from low in node2 to
561 * high in node1. 561 * high in node1.
562 */ 562 */
563 count = -count; 563 count = -count;
564 tmp = count * (uint)sizeof(xfs_da_node_entry_t); 564 tmp = count * (uint)sizeof(xfs_da_node_entry_t);
565 btree_s = &node2->btree[0]; 565 btree_s = &node2->btree[0];
566 btree_d = &node1->btree[INT_GET(node1->hdr.count, ARCH_CONVERT)]; 566 btree_d = &node1->btree[INT_GET(node1->hdr.count, ARCH_CONVERT)];
567 memcpy(btree_d, btree_s, tmp); 567 memcpy(btree_d, btree_s, tmp);
568 INT_MOD(node1->hdr.count, ARCH_CONVERT, count); 568 INT_MOD(node1->hdr.count, ARCH_CONVERT, count);
569 xfs_da_log_buf(tp, blk1->bp, 569 xfs_da_log_buf(tp, blk1->bp,
570 XFS_DA_LOGRANGE(node1, btree_d, tmp)); 570 XFS_DA_LOGRANGE(node1, btree_d, tmp));
571 571
572 /* 572 /*
573 * Move elements in node2 down to fill the hole. 573 * Move elements in node2 down to fill the hole.
574 */ 574 */
575 tmp = INT_GET(node2->hdr.count, ARCH_CONVERT) - count; 575 tmp = INT_GET(node2->hdr.count, ARCH_CONVERT) - count;
576 tmp *= (uint)sizeof(xfs_da_node_entry_t); 576 tmp *= (uint)sizeof(xfs_da_node_entry_t);
577 btree_s = &node2->btree[count]; 577 btree_s = &node2->btree[count];
578 btree_d = &node2->btree[0]; 578 btree_d = &node2->btree[0];
579 memmove(btree_d, btree_s, tmp); 579 memmove(btree_d, btree_s, tmp);
580 INT_MOD(node2->hdr.count, ARCH_CONVERT, -(count)); 580 INT_MOD(node2->hdr.count, ARCH_CONVERT, -(count));
581 } 581 }
582 582
583 /* 583 /*
584 * Log header of node 1 and all current bits of node 2. 584 * Log header of node 1 and all current bits of node 2.
585 */ 585 */
586 xfs_da_log_buf(tp, blk1->bp, 586 xfs_da_log_buf(tp, blk1->bp,
587 XFS_DA_LOGRANGE(node1, &node1->hdr, sizeof(node1->hdr))); 587 XFS_DA_LOGRANGE(node1, &node1->hdr, sizeof(node1->hdr)));
588 xfs_da_log_buf(tp, blk2->bp, 588 xfs_da_log_buf(tp, blk2->bp,
589 XFS_DA_LOGRANGE(node2, &node2->hdr, 589 XFS_DA_LOGRANGE(node2, &node2->hdr,
590 sizeof(node2->hdr) + 590 sizeof(node2->hdr) +
591 sizeof(node2->btree[0]) * INT_GET(node2->hdr.count, ARCH_CONVERT))); 591 sizeof(node2->btree[0]) * INT_GET(node2->hdr.count, ARCH_CONVERT)));
592 592
593 /* 593 /*
594 * Record the last hashval from each block for upward propagation. 594 * Record the last hashval from each block for upward propagation.
595 * (note: don't use the swapped node pointers) 595 * (note: don't use the swapped node pointers)
596 */ 596 */
597 node1 = blk1->bp->data; 597 node1 = blk1->bp->data;
598 node2 = blk2->bp->data; 598 node2 = blk2->bp->data;
599 blk1->hashval = INT_GET(node1->btree[ INT_GET(node1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); 599 blk1->hashval = INT_GET(node1->btree[ INT_GET(node1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
600 blk2->hashval = INT_GET(node2->btree[ INT_GET(node2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); 600 blk2->hashval = INT_GET(node2->btree[ INT_GET(node2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
601 601
602 /* 602 /*
603 * Adjust the expected index for insertion. 603 * Adjust the expected index for insertion.
604 */ 604 */
605 if (blk1->index >= INT_GET(node1->hdr.count, ARCH_CONVERT)) { 605 if (blk1->index >= INT_GET(node1->hdr.count, ARCH_CONVERT)) {
606 blk2->index = blk1->index - INT_GET(node1->hdr.count, ARCH_CONVERT); 606 blk2->index = blk1->index - INT_GET(node1->hdr.count, ARCH_CONVERT);
607 blk1->index = INT_GET(node1->hdr.count, ARCH_CONVERT) + 1; /* make it invalid */ 607 blk1->index = INT_GET(node1->hdr.count, ARCH_CONVERT) + 1; /* make it invalid */
608 } 608 }
609 } 609 }
610 610
611 /* 611 /*
612 * Add a new entry to an intermediate node. 612 * Add a new entry to an intermediate node.
613 */ 613 */
614 STATIC void 614 STATIC void
615 xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, 615 xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
616 xfs_da_state_blk_t *newblk) 616 xfs_da_state_blk_t *newblk)
617 { 617 {
618 xfs_da_intnode_t *node; 618 xfs_da_intnode_t *node;
619 xfs_da_node_entry_t *btree; 619 xfs_da_node_entry_t *btree;
620 int tmp; 620 int tmp;
621 xfs_mount_t *mp; 621 xfs_mount_t *mp;
622 622
623 node = oldblk->bp->data; 623 node = oldblk->bp->data;
624 mp = state->mp; 624 mp = state->mp;
625 ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); 625 ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
626 ASSERT((oldblk->index >= 0) && (oldblk->index <= INT_GET(node->hdr.count, ARCH_CONVERT))); 626 ASSERT((oldblk->index >= 0) && (oldblk->index <= INT_GET(node->hdr.count, ARCH_CONVERT)));
627 ASSERT(newblk->blkno != 0); 627 ASSERT(newblk->blkno != 0);
628 if (state->args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) 628 if (state->args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
629 ASSERT(newblk->blkno >= mp->m_dirleafblk && 629 ASSERT(newblk->blkno >= mp->m_dirleafblk &&
630 newblk->blkno < mp->m_dirfreeblk); 630 newblk->blkno < mp->m_dirfreeblk);
631 631
632 /* 632 /*
633 * We may need to make some room before we insert the new node. 633 * We may need to make some room before we insert the new node.
634 */ 634 */
635 tmp = 0; 635 tmp = 0;
636 btree = &node->btree[ oldblk->index ]; 636 btree = &node->btree[ oldblk->index ];
637 if (oldblk->index < INT_GET(node->hdr.count, ARCH_CONVERT)) { 637 if (oldblk->index < INT_GET(node->hdr.count, ARCH_CONVERT)) {
638 tmp = (INT_GET(node->hdr.count, ARCH_CONVERT) - oldblk->index) * (uint)sizeof(*btree); 638 tmp = (INT_GET(node->hdr.count, ARCH_CONVERT) - oldblk->index) * (uint)sizeof(*btree);
639 memmove(btree + 1, btree, tmp); 639 memmove(btree + 1, btree, tmp);
640 } 640 }
641 INT_SET(btree->hashval, ARCH_CONVERT, newblk->hashval); 641 INT_SET(btree->hashval, ARCH_CONVERT, newblk->hashval);
642 INT_SET(btree->before, ARCH_CONVERT, newblk->blkno); 642 INT_SET(btree->before, ARCH_CONVERT, newblk->blkno);
643 xfs_da_log_buf(state->args->trans, oldblk->bp, 643 xfs_da_log_buf(state->args->trans, oldblk->bp,
644 XFS_DA_LOGRANGE(node, btree, tmp + sizeof(*btree))); 644 XFS_DA_LOGRANGE(node, btree, tmp + sizeof(*btree)));
645 INT_MOD(node->hdr.count, ARCH_CONVERT, +1); 645 INT_MOD(node->hdr.count, ARCH_CONVERT, +1);
646 xfs_da_log_buf(state->args->trans, oldblk->bp, 646 xfs_da_log_buf(state->args->trans, oldblk->bp,
647 XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); 647 XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr)));
648 648
649 /* 649 /*
650 * Copy the last hash value from the oldblk to propagate upwards. 650 * Copy the last hash value from the oldblk to propagate upwards.
651 */ 651 */
652 oldblk->hashval = INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); 652 oldblk->hashval = INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
653 } 653 }
654 654
655 /*======================================================================== 655 /*========================================================================
656 * Routines used for shrinking the Btree. 656 * Routines used for shrinking the Btree.
657 *========================================================================*/ 657 *========================================================================*/
658 658
659 /* 659 /*
660 * Deallocate an empty leaf node, remove it from its parent, 660 * Deallocate an empty leaf node, remove it from its parent,
661 * possibly deallocating that block, etc... 661 * possibly deallocating that block, etc...
662 */ 662 */
663 int 663 int
664 xfs_da_join(xfs_da_state_t *state) 664 xfs_da_join(xfs_da_state_t *state)
665 { 665 {
666 xfs_da_state_blk_t *drop_blk, *save_blk; 666 xfs_da_state_blk_t *drop_blk, *save_blk;
667 int action, error; 667 int action, error;
668 668
669 action = 0; 669 action = 0;
670 drop_blk = &state->path.blk[ state->path.active-1 ]; 670 drop_blk = &state->path.blk[ state->path.active-1 ];
671 save_blk = &state->altpath.blk[ state->path.active-1 ]; 671 save_blk = &state->altpath.blk[ state->path.active-1 ];
672 ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC); 672 ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC);
673 ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC || 673 ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC ||
674 drop_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp)); 674 drop_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp));
675 675
676 /* 676 /*
677 * Walk back up the tree joining/deallocating as necessary. 677 * Walk back up the tree joining/deallocating as necessary.
678 * When we stop dropping blocks, break out. 678 * When we stop dropping blocks, break out.
679 */ 679 */
680 for ( ; state->path.active >= 2; drop_blk--, save_blk--, 680 for ( ; state->path.active >= 2; drop_blk--, save_blk--,
681 state->path.active--) { 681 state->path.active--) {
682 /* 682 /*
683 * See if we can combine the block with a neighbor. 683 * See if we can combine the block with a neighbor.
684 * (action == 0) => no options, just leave 684 * (action == 0) => no options, just leave
685 * (action == 1) => coalesce, then unlink 685 * (action == 1) => coalesce, then unlink
686 * (action == 2) => block empty, unlink it 686 * (action == 2) => block empty, unlink it
687 */ 687 */
688 switch (drop_blk->magic) { 688 switch (drop_blk->magic) {
689 case XFS_ATTR_LEAF_MAGIC: 689 case XFS_ATTR_LEAF_MAGIC:
690 error = xfs_attr_leaf_toosmall(state, &action); 690 error = xfs_attr_leaf_toosmall(state, &action);
691 if (error) 691 if (error)
692 return(error); 692 return(error);
693 if (action == 0) 693 if (action == 0)
694 return(0); 694 return(0);
695 xfs_attr_leaf_unbalance(state, drop_blk, save_blk); 695 xfs_attr_leaf_unbalance(state, drop_blk, save_blk);
696 break; 696 break;
697 case XFS_DIR_LEAF_MAGIC: 697 case XFS_DIR_LEAF_MAGIC:
698 ASSERT(XFS_DIR_IS_V1(state->mp)); 698 ASSERT(XFS_DIR_IS_V1(state->mp));
699 error = xfs_dir_leaf_toosmall(state, &action); 699 error = xfs_dir_leaf_toosmall(state, &action);
700 if (error) 700 if (error)
701 return(error); 701 return(error);
702 if (action == 0) 702 if (action == 0)
703 return(0); 703 return(0);
704 xfs_dir_leaf_unbalance(state, drop_blk, save_blk); 704 xfs_dir_leaf_unbalance(state, drop_blk, save_blk);
705 break; 705 break;
706 case XFS_DIR2_LEAFN_MAGIC: 706 case XFS_DIR2_LEAFN_MAGIC:
707 ASSERT(XFS_DIR_IS_V2(state->mp)); 707 ASSERT(XFS_DIR_IS_V2(state->mp));
708 error = xfs_dir2_leafn_toosmall(state, &action); 708 error = xfs_dir2_leafn_toosmall(state, &action);
709 if (error) 709 if (error)
710 return error; 710 return error;
711 if (action == 0) 711 if (action == 0)
712 return 0; 712 return 0;
713 xfs_dir2_leafn_unbalance(state, drop_blk, save_blk); 713 xfs_dir2_leafn_unbalance(state, drop_blk, save_blk);
714 break; 714 break;
715 case XFS_DA_NODE_MAGIC: 715 case XFS_DA_NODE_MAGIC:
716 /* 716 /*
717 * Remove the offending node, fixup hashvals, 717 * Remove the offending node, fixup hashvals,
718 * check for a toosmall neighbor. 718 * check for a toosmall neighbor.
719 */ 719 */
720 xfs_da_node_remove(state, drop_blk); 720 xfs_da_node_remove(state, drop_blk);
721 xfs_da_fixhashpath(state, &state->path); 721 xfs_da_fixhashpath(state, &state->path);
722 error = xfs_da_node_toosmall(state, &action); 722 error = xfs_da_node_toosmall(state, &action);
723 if (error) 723 if (error)
724 return(error); 724 return(error);
725 if (action == 0) 725 if (action == 0)
726 return 0; 726 return 0;
727 xfs_da_node_unbalance(state, drop_blk, save_blk); 727 xfs_da_node_unbalance(state, drop_blk, save_blk);
728 break; 728 break;
729 } 729 }
730 xfs_da_fixhashpath(state, &state->altpath); 730 xfs_da_fixhashpath(state, &state->altpath);
731 error = xfs_da_blk_unlink(state, drop_blk, save_blk); 731 error = xfs_da_blk_unlink(state, drop_blk, save_blk);
732 xfs_da_state_kill_altpath(state); 732 xfs_da_state_kill_altpath(state);
733 if (error) 733 if (error)
734 return(error); 734 return(error);
735 error = xfs_da_shrink_inode(state->args, drop_blk->blkno, 735 error = xfs_da_shrink_inode(state->args, drop_blk->blkno,
736 drop_blk->bp); 736 drop_blk->bp);
737 drop_blk->bp = NULL; 737 drop_blk->bp = NULL;
738 if (error) 738 if (error)
739 return(error); 739 return(error);
740 } 740 }
741 /* 741 /*
742 * We joined all the way to the top. If it turns out that 742 * We joined all the way to the top. If it turns out that
743 * we only have one entry in the root, make the child block 743 * we only have one entry in the root, make the child block
744 * the new root. 744 * the new root.
745 */ 745 */
746 xfs_da_node_remove(state, drop_blk); 746 xfs_da_node_remove(state, drop_blk);
747 xfs_da_fixhashpath(state, &state->path); 747 xfs_da_fixhashpath(state, &state->path);
748 error = xfs_da_root_join(state, &state->path.blk[0]); 748 error = xfs_da_root_join(state, &state->path.blk[0]);
749 return(error); 749 return(error);
750 } 750 }
751 751
752 /* 752 /*
753 * We have only one entry in the root. Copy the only remaining child of 753 * We have only one entry in the root. Copy the only remaining child of
754 * the old root to block 0 as the new root node. 754 * the old root to block 0 as the new root node.
755 */ 755 */
756 STATIC int 756 STATIC int
757 xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk) 757 xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)
758 { 758 {
759 xfs_da_intnode_t *oldroot; 759 xfs_da_intnode_t *oldroot;
760 /* REFERENCED */ 760 /* REFERENCED */
761 xfs_da_blkinfo_t *blkinfo; 761 xfs_da_blkinfo_t *blkinfo;
762 xfs_da_args_t *args; 762 xfs_da_args_t *args;
763 xfs_dablk_t child; 763 xfs_dablk_t child;
764 xfs_dabuf_t *bp; 764 xfs_dabuf_t *bp;
765 int error; 765 int error;
766 766
767 args = state->args; 767 args = state->args;
768 ASSERT(args != NULL); 768 ASSERT(args != NULL);
769 ASSERT(root_blk->magic == XFS_DA_NODE_MAGIC); 769 ASSERT(root_blk->magic == XFS_DA_NODE_MAGIC);
770 oldroot = root_blk->bp->data; 770 oldroot = root_blk->bp->data;
771 ASSERT(INT_GET(oldroot->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); 771 ASSERT(INT_GET(oldroot->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
772 ASSERT(!oldroot->hdr.info.forw); 772 ASSERT(!oldroot->hdr.info.forw);
773 ASSERT(!oldroot->hdr.info.back); 773 ASSERT(!oldroot->hdr.info.back);
774 774
775 /* 775 /*
776 * If the root has more than one child, then don't do anything. 776 * If the root has more than one child, then don't do anything.
777 */ 777 */
778 if (INT_GET(oldroot->hdr.count, ARCH_CONVERT) > 1) 778 if (INT_GET(oldroot->hdr.count, ARCH_CONVERT) > 1)
779 return(0); 779 return(0);
780 780
781 /* 781 /*
782 * Read in the (only) child block, then copy those bytes into 782 * Read in the (only) child block, then copy those bytes into
783 * the root block's buffer and free the original child block. 783 * the root block's buffer and free the original child block.
784 */ 784 */
785 child = INT_GET(oldroot->btree[ 0 ].before, ARCH_CONVERT); 785 child = INT_GET(oldroot->btree[ 0 ].before, ARCH_CONVERT);
786 ASSERT(child != 0); 786 ASSERT(child != 0);
787 error = xfs_da_read_buf(args->trans, args->dp, child, -1, &bp, 787 error = xfs_da_read_buf(args->trans, args->dp, child, -1, &bp,
788 args->whichfork); 788 args->whichfork);
789 if (error) 789 if (error)
790 return(error); 790 return(error);
791 ASSERT(bp != NULL); 791 ASSERT(bp != NULL);
792 blkinfo = bp->data; 792 blkinfo = bp->data;
793 if (INT_GET(oldroot->hdr.level, ARCH_CONVERT) == 1) { 793 if (INT_GET(oldroot->hdr.level, ARCH_CONVERT) == 1) {
794 ASSERT(INT_GET(blkinfo->magic, ARCH_CONVERT) == XFS_DIRX_LEAF_MAGIC(state->mp) || 794 ASSERT(INT_GET(blkinfo->magic, ARCH_CONVERT) == XFS_DIRX_LEAF_MAGIC(state->mp) ||
795 INT_GET(blkinfo->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC); 795 INT_GET(blkinfo->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC);
796 } else { 796 } else {
797 ASSERT(INT_GET(blkinfo->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); 797 ASSERT(INT_GET(blkinfo->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
798 } 798 }
799 ASSERT(!blkinfo->forw); 799 ASSERT(!blkinfo->forw);
800 ASSERT(!blkinfo->back); 800 ASSERT(!blkinfo->back);
801 memcpy(root_blk->bp->data, bp->data, state->blocksize); 801 memcpy(root_blk->bp->data, bp->data, state->blocksize);
802 xfs_da_log_buf(args->trans, root_blk->bp, 0, state->blocksize - 1); 802 xfs_da_log_buf(args->trans, root_blk->bp, 0, state->blocksize - 1);
803 error = xfs_da_shrink_inode(args, child, bp); 803 error = xfs_da_shrink_inode(args, child, bp);
804 return(error); 804 return(error);
805 } 805 }
806 806
807 /* 807 /*
808 * Check a node block and its neighbors to see if the block should be 808 * Check a node block and its neighbors to see if the block should be
809 * collapsed into one or the other neighbor. Always keep the block 809 * collapsed into one or the other neighbor. Always keep the block
810 * with the smaller block number. 810 * with the smaller block number.
811 * If the current block is over 50% full, don't try to join it, return 0. 811 * If the current block is over 50% full, don't try to join it, return 0.
812 * If the block is empty, fill in the state structure and return 2. 812 * If the block is empty, fill in the state structure and return 2.
813 * If it can be collapsed, fill in the state structure and return 1. 813 * If it can be collapsed, fill in the state structure and return 1.
814 * If nothing can be done, return 0. 814 * If nothing can be done, return 0.
815 */ 815 */
816 STATIC int 816 STATIC int
817 xfs_da_node_toosmall(xfs_da_state_t *state, int *action) 817 xfs_da_node_toosmall(xfs_da_state_t *state, int *action)
818 { 818 {
819 xfs_da_intnode_t *node; 819 xfs_da_intnode_t *node;
820 xfs_da_state_blk_t *blk; 820 xfs_da_state_blk_t *blk;
821 xfs_da_blkinfo_t *info; 821 xfs_da_blkinfo_t *info;
822 int count, forward, error, retval, i; 822 int count, forward, error, retval, i;
823 xfs_dablk_t blkno; 823 xfs_dablk_t blkno;
824 xfs_dabuf_t *bp; 824 xfs_dabuf_t *bp;
825 825
826 /* 826 /*
827 * Check for the degenerate case of the block being over 50% full. 827 * Check for the degenerate case of the block being over 50% full.
828 * If so, it's not worth even looking to see if we might be able 828 * If so, it's not worth even looking to see if we might be able
829 * to coalesce with a sibling. 829 * to coalesce with a sibling.
830 */ 830 */
831 blk = &state->path.blk[ state->path.active-1 ]; 831 blk = &state->path.blk[ state->path.active-1 ];
832 info = blk->bp->data; 832 info = blk->bp->data;
833 ASSERT(INT_GET(info->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); 833 ASSERT(INT_GET(info->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
834 node = (xfs_da_intnode_t *)info; 834 node = (xfs_da_intnode_t *)info;
835 count = INT_GET(node->hdr.count, ARCH_CONVERT); 835 count = INT_GET(node->hdr.count, ARCH_CONVERT);
836 if (count > (state->node_ents >> 1)) { 836 if (count > (state->node_ents >> 1)) {
837 *action = 0; /* blk over 50%, don't try to join */ 837 *action = 0; /* blk over 50%, don't try to join */
838 return(0); /* blk over 50%, don't try to join */ 838 return(0); /* blk over 50%, don't try to join */
839 } 839 }
840 840
841 /* 841 /*
842 * Check for the degenerate case of the block being empty. 842 * Check for the degenerate case of the block being empty.
843 * If the block is empty, we'll simply delete it, no need to 843 * If the block is empty, we'll simply delete it, no need to
844 * coalesce it with a sibling block. We choose (aribtrarily) 844 * coalesce it with a sibling block. We choose (aribtrarily)
845 * to merge with the forward block unless it is NULL. 845 * to merge with the forward block unless it is NULL.
846 */ 846 */
847 if (count == 0) { 847 if (count == 0) {
848 /* 848 /*
849 * Make altpath point to the block we want to keep and 849 * Make altpath point to the block we want to keep and
850 * path point to the block we want to drop (this one). 850 * path point to the block we want to drop (this one).
851 */ 851 */
852 forward = info->forw; 852 forward = info->forw;
853 memcpy(&state->altpath, &state->path, sizeof(state->path)); 853 memcpy(&state->altpath, &state->path, sizeof(state->path));
854 error = xfs_da_path_shift(state, &state->altpath, forward, 854 error = xfs_da_path_shift(state, &state->altpath, forward,
855 0, &retval); 855 0, &retval);
856 if (error) 856 if (error)
857 return(error); 857 return(error);
858 if (retval) { 858 if (retval) {
859 *action = 0; 859 *action = 0;
860 } else { 860 } else {
861 *action = 2; 861 *action = 2;
862 } 862 }
863 return(0); 863 return(0);
864 } 864 }
865 865
866 /* 866 /*
867 * Examine each sibling block to see if we can coalesce with 867 * Examine each sibling block to see if we can coalesce with
868 * at least 25% free space to spare. We need to figure out 868 * at least 25% free space to spare. We need to figure out
869 * whether to merge with the forward or the backward block. 869 * whether to merge with the forward or the backward block.
870 * We prefer coalescing with the lower numbered sibling so as 870 * We prefer coalescing with the lower numbered sibling so as
871 * to shrink a directory over time. 871 * to shrink a directory over time.
872 */ 872 */
873 /* start with smaller blk num */ 873 /* start with smaller blk num */
874 forward = (INT_GET(info->forw, ARCH_CONVERT) 874 forward = (INT_GET(info->forw, ARCH_CONVERT)
875 < INT_GET(info->back, ARCH_CONVERT)); 875 < INT_GET(info->back, ARCH_CONVERT));
876 for (i = 0; i < 2; forward = !forward, i++) { 876 for (i = 0; i < 2; forward = !forward, i++) {
877 if (forward) 877 if (forward)
878 blkno = INT_GET(info->forw, ARCH_CONVERT); 878 blkno = INT_GET(info->forw, ARCH_CONVERT);
879 else 879 else
880 blkno = INT_GET(info->back, ARCH_CONVERT); 880 blkno = INT_GET(info->back, ARCH_CONVERT);
881 if (blkno == 0) 881 if (blkno == 0)
882 continue; 882 continue;
883 error = xfs_da_read_buf(state->args->trans, state->args->dp, 883 error = xfs_da_read_buf(state->args->trans, state->args->dp,
884 blkno, -1, &bp, state->args->whichfork); 884 blkno, -1, &bp, state->args->whichfork);
885 if (error) 885 if (error)
886 return(error); 886 return(error);
887 ASSERT(bp != NULL); 887 ASSERT(bp != NULL);
888 888
889 node = (xfs_da_intnode_t *)info; 889 node = (xfs_da_intnode_t *)info;
890 count = state->node_ents; 890 count = state->node_ents;
891 count -= state->node_ents >> 2; 891 count -= state->node_ents >> 2;
892 count -= INT_GET(node->hdr.count, ARCH_CONVERT); 892 count -= INT_GET(node->hdr.count, ARCH_CONVERT);
893 node = bp->data; 893 node = bp->data;
894 ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); 894 ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
895 count -= INT_GET(node->hdr.count, ARCH_CONVERT); 895 count -= INT_GET(node->hdr.count, ARCH_CONVERT);
896 xfs_da_brelse(state->args->trans, bp); 896 xfs_da_brelse(state->args->trans, bp);
897 if (count >= 0) 897 if (count >= 0)
898 break; /* fits with at least 25% to spare */ 898 break; /* fits with at least 25% to spare */
899 } 899 }
900 if (i >= 2) { 900 if (i >= 2) {
901 *action = 0; 901 *action = 0;
902 return(0); 902 return(0);
903 } 903 }
904 904
905 /* 905 /*
906 * Make altpath point to the block we want to keep (the lower 906 * Make altpath point to the block we want to keep (the lower
907 * numbered block) and path point to the block we want to drop. 907 * numbered block) and path point to the block we want to drop.
908 */ 908 */
909 memcpy(&state->altpath, &state->path, sizeof(state->path)); 909 memcpy(&state->altpath, &state->path, sizeof(state->path));
910 if (blkno < blk->blkno) { 910 if (blkno < blk->blkno) {
911 error = xfs_da_path_shift(state, &state->altpath, forward, 911 error = xfs_da_path_shift(state, &state->altpath, forward,
912 0, &retval); 912 0, &retval);
913 if (error) { 913 if (error) {
914 return(error); 914 return(error);
915 } 915 }
916 if (retval) { 916 if (retval) {
917 *action = 0; 917 *action = 0;
918 return(0); 918 return(0);
919 } 919 }
920 } else { 920 } else {
921 error = xfs_da_path_shift(state, &state->path, forward, 921 error = xfs_da_path_shift(state, &state->path, forward,
922 0, &retval); 922 0, &retval);
923 if (error) { 923 if (error) {
924 return(error); 924 return(error);
925 } 925 }
926 if (retval) { 926 if (retval) {
927 *action = 0; 927 *action = 0;
928 return(0); 928 return(0);
929 } 929 }
930 } 930 }
931 *action = 1; 931 *action = 1;
932 return(0); 932 return(0);
933 } 933 }
934 934
935 /* 935 /*
936 * Walk back up the tree adjusting hash values as necessary, 936 * Walk back up the tree adjusting hash values as necessary,
937 * when we stop making changes, return. 937 * when we stop making changes, return.
938 */ 938 */
939 void 939 void
940 xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path) 940 xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path)
941 { 941 {
942 xfs_da_state_blk_t *blk; 942 xfs_da_state_blk_t *blk;
943 xfs_da_intnode_t *node; 943 xfs_da_intnode_t *node;
944 xfs_da_node_entry_t *btree; 944 xfs_da_node_entry_t *btree;
945 xfs_dahash_t lasthash=0; 945 xfs_dahash_t lasthash=0;
946 int level, count; 946 int level, count;
947 947
948 level = path->active-1; 948 level = path->active-1;
949 blk = &path->blk[ level ]; 949 blk = &path->blk[ level ];
950 switch (blk->magic) { 950 switch (blk->magic) {
951 case XFS_ATTR_LEAF_MAGIC: 951 case XFS_ATTR_LEAF_MAGIC:
952 lasthash = xfs_attr_leaf_lasthash(blk->bp, &count); 952 lasthash = xfs_attr_leaf_lasthash(blk->bp, &count);
953 if (count == 0) 953 if (count == 0)
954 return; 954 return;
955 break; 955 break;
956 case XFS_DIR_LEAF_MAGIC: 956 case XFS_DIR_LEAF_MAGIC:
957 ASSERT(XFS_DIR_IS_V1(state->mp)); 957 ASSERT(XFS_DIR_IS_V1(state->mp));
958 lasthash = xfs_dir_leaf_lasthash(blk->bp, &count); 958 lasthash = xfs_dir_leaf_lasthash(blk->bp, &count);
959 if (count == 0) 959 if (count == 0)
960 return; 960 return;
961 break; 961 break;
962 case XFS_DIR2_LEAFN_MAGIC: 962 case XFS_DIR2_LEAFN_MAGIC:
963 ASSERT(XFS_DIR_IS_V2(state->mp)); 963 ASSERT(XFS_DIR_IS_V2(state->mp));
964 lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count); 964 lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count);
965 if (count == 0) 965 if (count == 0)
966 return; 966 return;
967 break; 967 break;
968 case XFS_DA_NODE_MAGIC: 968 case XFS_DA_NODE_MAGIC:
969 lasthash = xfs_da_node_lasthash(blk->bp, &count); 969 lasthash = xfs_da_node_lasthash(blk->bp, &count);
970 if (count == 0) 970 if (count == 0)
971 return; 971 return;
972 break; 972 break;
973 } 973 }
974 for (blk--, level--; level >= 0; blk--, level--) { 974 for (blk--, level--; level >= 0; blk--, level--) {
975 node = blk->bp->data; 975 node = blk->bp->data;
976 ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); 976 ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
977 btree = &node->btree[ blk->index ]; 977 btree = &node->btree[ blk->index ];
978 if (INT_GET(btree->hashval, ARCH_CONVERT) == lasthash) 978 if (INT_GET(btree->hashval, ARCH_CONVERT) == lasthash)
979 break; 979 break;
980 blk->hashval = lasthash; 980 blk->hashval = lasthash;
981 INT_SET(btree->hashval, ARCH_CONVERT, lasthash); 981 INT_SET(btree->hashval, ARCH_CONVERT, lasthash);
982 xfs_da_log_buf(state->args->trans, blk->bp, 982 xfs_da_log_buf(state->args->trans, blk->bp,
983 XFS_DA_LOGRANGE(node, btree, sizeof(*btree))); 983 XFS_DA_LOGRANGE(node, btree, sizeof(*btree)));
984 984
985 lasthash = INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); 985 lasthash = INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
986 } 986 }
987 } 987 }
988 988
989 /* 989 /*
990 * Remove an entry from an intermediate node. 990 * Remove an entry from an intermediate node.
991 */ 991 */
992 STATIC void 992 STATIC void
993 xfs_da_node_remove(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk) 993 xfs_da_node_remove(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk)
994 { 994 {
995 xfs_da_intnode_t *node; 995 xfs_da_intnode_t *node;
996 xfs_da_node_entry_t *btree; 996 xfs_da_node_entry_t *btree;
997 int tmp; 997 int tmp;
998 998
999 node = drop_blk->bp->data; 999 node = drop_blk->bp->data;
1000 ASSERT(drop_blk->index < INT_GET(node->hdr.count, ARCH_CONVERT)); 1000 ASSERT(drop_blk->index < INT_GET(node->hdr.count, ARCH_CONVERT));
1001 ASSERT(drop_blk->index >= 0); 1001 ASSERT(drop_blk->index >= 0);
1002 1002
1003 /* 1003 /*
1004 * Copy over the offending entry, or just zero it out. 1004 * Copy over the offending entry, or just zero it out.
1005 */ 1005 */
1006 btree = &node->btree[drop_blk->index]; 1006 btree = &node->btree[drop_blk->index];
1007 if (drop_blk->index < (INT_GET(node->hdr.count, ARCH_CONVERT)-1)) { 1007 if (drop_blk->index < (INT_GET(node->hdr.count, ARCH_CONVERT)-1)) {
1008 tmp = INT_GET(node->hdr.count, ARCH_CONVERT) - drop_blk->index - 1; 1008 tmp = INT_GET(node->hdr.count, ARCH_CONVERT) - drop_blk->index - 1;
1009 tmp *= (uint)sizeof(xfs_da_node_entry_t); 1009 tmp *= (uint)sizeof(xfs_da_node_entry_t);
1010 memmove(btree, btree + 1, tmp); 1010 memmove(btree, btree + 1, tmp);
1011 xfs_da_log_buf(state->args->trans, drop_blk->bp, 1011 xfs_da_log_buf(state->args->trans, drop_blk->bp,
1012 XFS_DA_LOGRANGE(node, btree, tmp)); 1012 XFS_DA_LOGRANGE(node, btree, tmp));
1013 btree = &node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ]; 1013 btree = &node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ];
1014 } 1014 }
1015 memset((char *)btree, 0, sizeof(xfs_da_node_entry_t)); 1015 memset((char *)btree, 0, sizeof(xfs_da_node_entry_t));
1016 xfs_da_log_buf(state->args->trans, drop_blk->bp, 1016 xfs_da_log_buf(state->args->trans, drop_blk->bp,
1017 XFS_DA_LOGRANGE(node, btree, sizeof(*btree))); 1017 XFS_DA_LOGRANGE(node, btree, sizeof(*btree)));
1018 INT_MOD(node->hdr.count, ARCH_CONVERT, -1); 1018 INT_MOD(node->hdr.count, ARCH_CONVERT, -1);
1019 xfs_da_log_buf(state->args->trans, drop_blk->bp, 1019 xfs_da_log_buf(state->args->trans, drop_blk->bp,
1020 XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); 1020 XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr)));
1021 1021
1022 /* 1022 /*
1023 * Copy the last hash value from the block to propagate upwards. 1023 * Copy the last hash value from the block to propagate upwards.
1024 */ 1024 */
1025 btree--; 1025 btree--;
1026 drop_blk->hashval = INT_GET(btree->hashval, ARCH_CONVERT); 1026 drop_blk->hashval = INT_GET(btree->hashval, ARCH_CONVERT);
1027 } 1027 }
1028 1028
1029 /* 1029 /*
1030 * Unbalance the btree elements between two intermediate nodes, 1030 * Unbalance the btree elements between two intermediate nodes,
1031 * move all Btree elements from one node into another. 1031 * move all Btree elements from one node into another.
1032 */ 1032 */
1033 STATIC void 1033 STATIC void
1034 xfs_da_node_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, 1034 xfs_da_node_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
1035 xfs_da_state_blk_t *save_blk) 1035 xfs_da_state_blk_t *save_blk)
1036 { 1036 {
1037 xfs_da_intnode_t *drop_node, *save_node; 1037 xfs_da_intnode_t *drop_node, *save_node;
1038 xfs_da_node_entry_t *btree; 1038 xfs_da_node_entry_t *btree;
1039 int tmp; 1039 int tmp;
1040 xfs_trans_t *tp; 1040 xfs_trans_t *tp;
1041 1041
1042 drop_node = drop_blk->bp->data; 1042 drop_node = drop_blk->bp->data;
1043 save_node = save_blk->bp->data; 1043 save_node = save_blk->bp->data;
1044 ASSERT(INT_GET(drop_node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); 1044 ASSERT(INT_GET(drop_node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
1045 ASSERT(INT_GET(save_node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); 1045 ASSERT(INT_GET(save_node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
1046 tp = state->args->trans; 1046 tp = state->args->trans;
1047 1047
1048 /* 1048 /*
1049 * If the dying block has lower hashvals, then move all the 1049 * If the dying block has lower hashvals, then move all the
1050 * elements in the remaining block up to make a hole. 1050 * elements in the remaining block up to make a hole.
1051 */ 1051 */
1052 if ((INT_GET(drop_node->btree[ 0 ].hashval, ARCH_CONVERT) < INT_GET(save_node->btree[ 0 ].hashval, ARCH_CONVERT)) || 1052 if ((INT_GET(drop_node->btree[ 0 ].hashval, ARCH_CONVERT) < INT_GET(save_node->btree[ 0 ].hashval, ARCH_CONVERT)) ||
1053 (INT_GET(drop_node->btree[ INT_GET(drop_node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT) < 1053 (INT_GET(drop_node->btree[ INT_GET(drop_node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT) <
1054 INT_GET(save_node->btree[ INT_GET(save_node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT))) 1054 INT_GET(save_node->btree[ INT_GET(save_node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)))
1055 { 1055 {
1056 btree = &save_node->btree[ INT_GET(drop_node->hdr.count, ARCH_CONVERT) ]; 1056 btree = &save_node->btree[ INT_GET(drop_node->hdr.count, ARCH_CONVERT) ];
1057 tmp = INT_GET(save_node->hdr.count, ARCH_CONVERT) * (uint)sizeof(xfs_da_node_entry_t); 1057 tmp = INT_GET(save_node->hdr.count, ARCH_CONVERT) * (uint)sizeof(xfs_da_node_entry_t);
1058 memmove(btree, &save_node->btree[0], tmp); 1058 memmove(btree, &save_node->btree[0], tmp);
1059 btree = &save_node->btree[0]; 1059 btree = &save_node->btree[0];
1060 xfs_da_log_buf(tp, save_blk->bp, 1060 xfs_da_log_buf(tp, save_blk->bp,
1061 XFS_DA_LOGRANGE(save_node, btree, 1061 XFS_DA_LOGRANGE(save_node, btree,
1062 (INT_GET(save_node->hdr.count, ARCH_CONVERT) + INT_GET(drop_node->hdr.count, ARCH_CONVERT)) * 1062 (INT_GET(save_node->hdr.count, ARCH_CONVERT) + INT_GET(drop_node->hdr.count, ARCH_CONVERT)) *
1063 sizeof(xfs_da_node_entry_t))); 1063 sizeof(xfs_da_node_entry_t)));
1064 } else { 1064 } else {
1065 btree = &save_node->btree[ INT_GET(save_node->hdr.count, ARCH_CONVERT) ]; 1065 btree = &save_node->btree[ INT_GET(save_node->hdr.count, ARCH_CONVERT) ];
1066 xfs_da_log_buf(tp, save_blk->bp, 1066 xfs_da_log_buf(tp, save_blk->bp,
1067 XFS_DA_LOGRANGE(save_node, btree, 1067 XFS_DA_LOGRANGE(save_node, btree,
1068 INT_GET(drop_node->hdr.count, ARCH_CONVERT) * 1068 INT_GET(drop_node->hdr.count, ARCH_CONVERT) *
1069 sizeof(xfs_da_node_entry_t))); 1069 sizeof(xfs_da_node_entry_t)));
1070 } 1070 }
1071 1071
1072 /* 1072 /*
1073 * Move all the B-tree elements from drop_blk to save_blk. 1073 * Move all the B-tree elements from drop_blk to save_blk.
1074 */ 1074 */
1075 tmp = INT_GET(drop_node->hdr.count, ARCH_CONVERT) * (uint)sizeof(xfs_da_node_entry_t); 1075 tmp = INT_GET(drop_node->hdr.count, ARCH_CONVERT) * (uint)sizeof(xfs_da_node_entry_t);
1076 memcpy(btree, &drop_node->btree[0], tmp); 1076 memcpy(btree, &drop_node->btree[0], tmp);
1077 INT_MOD(save_node->hdr.count, ARCH_CONVERT, INT_GET(drop_node->hdr.count, ARCH_CONVERT)); 1077 INT_MOD(save_node->hdr.count, ARCH_CONVERT, INT_GET(drop_node->hdr.count, ARCH_CONVERT));
1078 1078
1079 xfs_da_log_buf(tp, save_blk->bp, 1079 xfs_da_log_buf(tp, save_blk->bp,
1080 XFS_DA_LOGRANGE(save_node, &save_node->hdr, 1080 XFS_DA_LOGRANGE(save_node, &save_node->hdr,
1081 sizeof(save_node->hdr))); 1081 sizeof(save_node->hdr)));
1082 1082
1083 /* 1083 /*
1084 * Save the last hashval in the remaining block for upward propagation. 1084 * Save the last hashval in the remaining block for upward propagation.
1085 */ 1085 */
1086 save_blk->hashval = INT_GET(save_node->btree[ INT_GET(save_node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); 1086 save_blk->hashval = INT_GET(save_node->btree[ INT_GET(save_node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
1087 } 1087 }
1088 1088
1089 /*======================================================================== 1089 /*========================================================================
1090 * Routines used for finding things in the Btree. 1090 * Routines used for finding things in the Btree.
1091 *========================================================================*/ 1091 *========================================================================*/
1092 1092
1093 /* 1093 /*
1094 * Walk down the Btree looking for a particular filename, filling 1094 * Walk down the Btree looking for a particular filename, filling
1095 * in the state structure as we go. 1095 * in the state structure as we go.
1096 * 1096 *
1097 * We will set the state structure to point to each of the elements 1097 * We will set the state structure to point to each of the elements
1098 * in each of the nodes where either the hashval is or should be. 1098 * in each of the nodes where either the hashval is or should be.
1099 * 1099 *
1100 * We support duplicate hashval's so for each entry in the current 1100 * We support duplicate hashval's so for each entry in the current
1101 * node that could contain the desired hashval, descend. This is a 1101 * node that could contain the desired hashval, descend. This is a
1102 * pruned depth-first tree search. 1102 * pruned depth-first tree search.
1103 */ 1103 */
1104 int /* error */ 1104 int /* error */
1105 xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) 1105 xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
1106 { 1106 {
1107 xfs_da_state_blk_t *blk; 1107 xfs_da_state_blk_t *blk;
1108 xfs_da_blkinfo_t *curr; 1108 xfs_da_blkinfo_t *curr;
1109 xfs_da_intnode_t *node; 1109 xfs_da_intnode_t *node;
1110 xfs_da_node_entry_t *btree; 1110 xfs_da_node_entry_t *btree;
1111 xfs_dablk_t blkno; 1111 xfs_dablk_t blkno;
1112 int probe, span, max, error, retval; 1112 int probe, span, max, error, retval;
1113 xfs_dahash_t hashval; 1113 xfs_dahash_t hashval;
1114 xfs_da_args_t *args; 1114 xfs_da_args_t *args;
1115 1115
1116 args = state->args; 1116 args = state->args;
1117 1117
1118 /* 1118 /*
1119 * Descend thru the B-tree searching each level for the right 1119 * Descend thru the B-tree searching each level for the right
1120 * node to use, until the right hashval is found. 1120 * node to use, until the right hashval is found.
1121 */ 1121 */
1122 if (args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(state->mp)) 1122 if (args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(state->mp))
1123 blkno = state->mp->m_dirleafblk; 1123 blkno = state->mp->m_dirleafblk;
1124 else 1124 else
1125 blkno = 0; 1125 blkno = 0;
1126 for (blk = &state->path.blk[0], state->path.active = 1; 1126 for (blk = &state->path.blk[0], state->path.active = 1;
1127 state->path.active <= XFS_DA_NODE_MAXDEPTH; 1127 state->path.active <= XFS_DA_NODE_MAXDEPTH;
1128 blk++, state->path.active++) { 1128 blk++, state->path.active++) {
1129 /* 1129 /*
1130 * Read the next node down in the tree. 1130 * Read the next node down in the tree.
1131 */ 1131 */
1132 blk->blkno = blkno; 1132 blk->blkno = blkno;
1133 error = xfs_da_read_buf(args->trans, args->dp, blkno, 1133 error = xfs_da_read_buf(args->trans, args->dp, blkno,
1134 -1, &blk->bp, args->whichfork); 1134 -1, &blk->bp, args->whichfork);
1135 if (error) { 1135 if (error) {
1136 blk->blkno = 0; 1136 blk->blkno = 0;
1137 state->path.active--; 1137 state->path.active--;
1138 return(error); 1138 return(error);
1139 } 1139 }
1140 curr = blk->bp->data; 1140 curr = blk->bp->data;
1141 ASSERT(INT_GET(curr->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC || 1141 ASSERT(INT_GET(curr->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC ||
1142 INT_GET(curr->magic, ARCH_CONVERT) == XFS_DIRX_LEAF_MAGIC(state->mp) || 1142 INT_GET(curr->magic, ARCH_CONVERT) == XFS_DIRX_LEAF_MAGIC(state->mp) ||
1143 INT_GET(curr->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC); 1143 INT_GET(curr->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC);
1144 1144
1145 /* 1145 /*
1146 * Search an intermediate node for a match. 1146 * Search an intermediate node for a match.
1147 */ 1147 */
1148 blk->magic = INT_GET(curr->magic, ARCH_CONVERT); 1148 blk->magic = INT_GET(curr->magic, ARCH_CONVERT);
1149 if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC) { 1149 if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC) {
1150 node = blk->bp->data; 1150 node = blk->bp->data;
1151 blk->hashval = INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); 1151 blk->hashval = INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
1152 1152
1153 /* 1153 /*
1154 * Binary search. (note: small blocks will skip loop) 1154 * Binary search. (note: small blocks will skip loop)
1155 */ 1155 */
1156 max = INT_GET(node->hdr.count, ARCH_CONVERT); 1156 max = INT_GET(node->hdr.count, ARCH_CONVERT);
1157 probe = span = max / 2; 1157 probe = span = max / 2;
1158 hashval = args->hashval; 1158 hashval = args->hashval;
1159 for (btree = &node->btree[probe]; span > 4; 1159 for (btree = &node->btree[probe]; span > 4;
1160 btree = &node->btree[probe]) { 1160 btree = &node->btree[probe]) {
1161 span /= 2; 1161 span /= 2;
1162 if (INT_GET(btree->hashval, ARCH_CONVERT) < hashval) 1162 if (INT_GET(btree->hashval, ARCH_CONVERT) < hashval)
1163 probe += span; 1163 probe += span;
1164 else if (INT_GET(btree->hashval, ARCH_CONVERT) > hashval) 1164 else if (INT_GET(btree->hashval, ARCH_CONVERT) > hashval)
1165 probe -= span; 1165 probe -= span;
1166 else 1166 else
1167 break; 1167 break;
1168 } 1168 }
1169 ASSERT((probe >= 0) && (probe < max)); 1169 ASSERT((probe >= 0) && (probe < max));
1170 ASSERT((span <= 4) || (INT_GET(btree->hashval, ARCH_CONVERT) == hashval)); 1170 ASSERT((span <= 4) || (INT_GET(btree->hashval, ARCH_CONVERT) == hashval));
1171 1171
1172 /* 1172 /*
1173 * Since we may have duplicate hashval's, find the first 1173 * Since we may have duplicate hashval's, find the first
1174 * matching hashval in the node. 1174 * matching hashval in the node.
1175 */ 1175 */
1176 while ((probe > 0) && (INT_GET(btree->hashval, ARCH_CONVERT) >= hashval)) { 1176 while ((probe > 0) && (INT_GET(btree->hashval, ARCH_CONVERT) >= hashval)) {
1177 btree--; 1177 btree--;
1178 probe--; 1178 probe--;
1179 } 1179 }
1180 while ((probe < max) && (INT_GET(btree->hashval, ARCH_CONVERT) < hashval)) { 1180 while ((probe < max) && (INT_GET(btree->hashval, ARCH_CONVERT) < hashval)) {
1181 btree++; 1181 btree++;
1182 probe++; 1182 probe++;
1183 } 1183 }
1184 1184
1185 /* 1185 /*
1186 * Pick the right block to descend on. 1186 * Pick the right block to descend on.
1187 */ 1187 */
1188 if (probe == max) { 1188 if (probe == max) {
1189 blk->index = max-1; 1189 blk->index = max-1;
1190 blkno = INT_GET(node->btree[ max-1 ].before, ARCH_CONVERT); 1190 blkno = INT_GET(node->btree[ max-1 ].before, ARCH_CONVERT);
1191 } else { 1191 } else {
1192 blk->index = probe; 1192 blk->index = probe;
1193 blkno = INT_GET(btree->before, ARCH_CONVERT); 1193 blkno = INT_GET(btree->before, ARCH_CONVERT);
1194 } 1194 }
1195 } 1195 }
1196 else if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC) { 1196 else if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC) {
1197 blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); 1197 blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);
1198 break; 1198 break;
1199 } 1199 }
1200 else if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC) { 1200 else if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC) {
1201 blk->hashval = xfs_dir_leaf_lasthash(blk->bp, NULL); 1201 blk->hashval = xfs_dir_leaf_lasthash(blk->bp, NULL);
1202 break; 1202 break;
1203 } 1203 }
1204 else if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC) { 1204 else if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC) {
1205 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); 1205 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL);
1206 break; 1206 break;
1207 } 1207 }
1208 } 1208 }
1209 1209
1210 /* 1210 /*
1211 * A leaf block that ends in the hashval that we are interested in 1211 * A leaf block that ends in the hashval that we are interested in
1212 * (final hashval == search hashval) means that the next block may 1212 * (final hashval == search hashval) means that the next block may
1213 * contain more entries with the same hashval, shift upward to the 1213 * contain more entries with the same hashval, shift upward to the
1214 * next leaf and keep searching. 1214 * next leaf and keep searching.
1215 */ 1215 */
1216 for (;;) { 1216 for (;;) {
1217 if (blk->magic == XFS_DIR_LEAF_MAGIC) { 1217 if (blk->magic == XFS_DIR_LEAF_MAGIC) {
1218 ASSERT(XFS_DIR_IS_V1(state->mp)); 1218 ASSERT(XFS_DIR_IS_V1(state->mp));
1219 retval = xfs_dir_leaf_lookup_int(blk->bp, args, 1219 retval = xfs_dir_leaf_lookup_int(blk->bp, args,
1220 &blk->index); 1220 &blk->index);
1221 } else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { 1221 } else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
1222 ASSERT(XFS_DIR_IS_V2(state->mp)); 1222 ASSERT(XFS_DIR_IS_V2(state->mp));
1223 retval = xfs_dir2_leafn_lookup_int(blk->bp, args, 1223 retval = xfs_dir2_leafn_lookup_int(blk->bp, args,
1224 &blk->index, state); 1224 &blk->index, state);
1225 } 1225 }
1226 else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { 1226 else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
1227 retval = xfs_attr_leaf_lookup_int(blk->bp, args); 1227 retval = xfs_attr_leaf_lookup_int(blk->bp, args);
1228 blk->index = args->index; 1228 blk->index = args->index;
1229 args->blkno = blk->blkno; 1229 args->blkno = blk->blkno;
1230 } 1230 }
1231 if (((retval == ENOENT) || (retval == ENOATTR)) && 1231 if (((retval == ENOENT) || (retval == ENOATTR)) &&
1232 (blk->hashval == args->hashval)) { 1232 (blk->hashval == args->hashval)) {
1233 error = xfs_da_path_shift(state, &state->path, 1, 1, 1233 error = xfs_da_path_shift(state, &state->path, 1, 1,
1234 &retval); 1234 &retval);
1235 if (error) 1235 if (error)
1236 return(error); 1236 return(error);
1237 if (retval == 0) { 1237 if (retval == 0) {
1238 continue; 1238 continue;
1239 } 1239 }
1240 else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { 1240 else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
1241 /* path_shift() gives ENOENT */ 1241 /* path_shift() gives ENOENT */
1242 retval = XFS_ERROR(ENOATTR); 1242 retval = XFS_ERROR(ENOATTR);
1243 } 1243 }
1244 } 1244 }
1245 break; 1245 break;
1246 } 1246 }
1247 *result = retval; 1247 *result = retval;
1248 return(0); 1248 return(0);
1249 } 1249 }
1250 1250
1251 /*======================================================================== 1251 /*========================================================================
1252 * Utility routines. 1252 * Utility routines.
1253 *========================================================================*/ 1253 *========================================================================*/
1254 1254
1255 /* 1255 /*
1256 * Link a new block into a doubly linked list of blocks (of whatever type). 1256 * Link a new block into a doubly linked list of blocks (of whatever type).
1257 */ 1257 */
1258 int /* error */ 1258 int /* error */
1259 xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, 1259 xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
1260 xfs_da_state_blk_t *new_blk) 1260 xfs_da_state_blk_t *new_blk)
1261 { 1261 {
1262 xfs_da_blkinfo_t *old_info, *new_info, *tmp_info; 1262 xfs_da_blkinfo_t *old_info, *new_info, *tmp_info;
1263 xfs_da_args_t *args; 1263 xfs_da_args_t *args;
1264 int before=0, error; 1264 int before=0, error;
1265 xfs_dabuf_t *bp; 1265 xfs_dabuf_t *bp;
1266 1266
1267 /* 1267 /*
1268 * Set up environment. 1268 * Set up environment.
1269 */ 1269 */
1270 args = state->args; 1270 args = state->args;
1271 ASSERT(args != NULL); 1271 ASSERT(args != NULL);
1272 old_info = old_blk->bp->data; 1272 old_info = old_blk->bp->data;
1273 new_info = new_blk->bp->data; 1273 new_info = new_blk->bp->data;
1274 ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC || 1274 ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC ||
1275 old_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) || 1275 old_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) ||
1276 old_blk->magic == XFS_ATTR_LEAF_MAGIC); 1276 old_blk->magic == XFS_ATTR_LEAF_MAGIC);
1277 ASSERT(old_blk->magic == INT_GET(old_info->magic, ARCH_CONVERT)); 1277 ASSERT(old_blk->magic == INT_GET(old_info->magic, ARCH_CONVERT));
1278 ASSERT(new_blk->magic == INT_GET(new_info->magic, ARCH_CONVERT)); 1278 ASSERT(new_blk->magic == INT_GET(new_info->magic, ARCH_CONVERT));
1279 ASSERT(old_blk->magic == new_blk->magic); 1279 ASSERT(old_blk->magic == new_blk->magic);
1280 1280
1281 switch (old_blk->magic) { 1281 switch (old_blk->magic) {
1282 case XFS_ATTR_LEAF_MAGIC: 1282 case XFS_ATTR_LEAF_MAGIC:
1283 before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp); 1283 before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp);
1284 break; 1284 break;
1285 case XFS_DIR_LEAF_MAGIC: 1285 case XFS_DIR_LEAF_MAGIC:
1286 ASSERT(XFS_DIR_IS_V1(state->mp)); 1286 ASSERT(XFS_DIR_IS_V1(state->mp));
1287 before = xfs_dir_leaf_order(old_blk->bp, new_blk->bp); 1287 before = xfs_dir_leaf_order(old_blk->bp, new_blk->bp);
1288 break; 1288 break;
1289 case XFS_DIR2_LEAFN_MAGIC: 1289 case XFS_DIR2_LEAFN_MAGIC:
1290 ASSERT(XFS_DIR_IS_V2(state->mp)); 1290 ASSERT(XFS_DIR_IS_V2(state->mp));
1291 before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp); 1291 before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp);
1292 break; 1292 break;
1293 case XFS_DA_NODE_MAGIC: 1293 case XFS_DA_NODE_MAGIC:
1294 before = xfs_da_node_order(old_blk->bp, new_blk->bp); 1294 before = xfs_da_node_order(old_blk->bp, new_blk->bp);
1295 break; 1295 break;
1296 } 1296 }
1297 1297
1298 /* 1298 /*
1299 * Link blocks in appropriate order. 1299 * Link blocks in appropriate order.
1300 */ 1300 */
1301 if (before) { 1301 if (before) {
1302 /* 1302 /*
1303 * Link new block in before existing block. 1303 * Link new block in before existing block.
1304 */ 1304 */
1305 INT_SET(new_info->forw, ARCH_CONVERT, old_blk->blkno); 1305 INT_SET(new_info->forw, ARCH_CONVERT, old_blk->blkno);
1306 new_info->back = old_info->back; /* INT_: direct copy */ 1306 new_info->back = old_info->back; /* INT_: direct copy */
1307 if (INT_GET(old_info->back, ARCH_CONVERT)) { 1307 if (INT_GET(old_info->back, ARCH_CONVERT)) {
1308 error = xfs_da_read_buf(args->trans, args->dp, 1308 error = xfs_da_read_buf(args->trans, args->dp,
1309 INT_GET(old_info->back, 1309 INT_GET(old_info->back,
1310 ARCH_CONVERT), -1, &bp, 1310 ARCH_CONVERT), -1, &bp,
1311 args->whichfork); 1311 args->whichfork);
1312 if (error) 1312 if (error)
1313 return(error); 1313 return(error);
1314 ASSERT(bp != NULL); 1314 ASSERT(bp != NULL);
1315 tmp_info = bp->data; 1315 tmp_info = bp->data;
1316 ASSERT(INT_GET(tmp_info->magic, ARCH_CONVERT) == INT_GET(old_info->magic, ARCH_CONVERT)); 1316 ASSERT(INT_GET(tmp_info->magic, ARCH_CONVERT) == INT_GET(old_info->magic, ARCH_CONVERT));
1317 ASSERT(INT_GET(tmp_info->forw, ARCH_CONVERT) == old_blk->blkno); 1317 ASSERT(INT_GET(tmp_info->forw, ARCH_CONVERT) == old_blk->blkno);
1318 INT_SET(tmp_info->forw, ARCH_CONVERT, new_blk->blkno); 1318 INT_SET(tmp_info->forw, ARCH_CONVERT, new_blk->blkno);
1319 xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1); 1319 xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1);
1320 xfs_da_buf_done(bp); 1320 xfs_da_buf_done(bp);
1321 } 1321 }
1322 INT_SET(old_info->back, ARCH_CONVERT, new_blk->blkno); 1322 INT_SET(old_info->back, ARCH_CONVERT, new_blk->blkno);
1323 } else { 1323 } else {
1324 /* 1324 /*
1325 * Link new block in after existing block. 1325 * Link new block in after existing block.
1326 */ 1326 */
1327 new_info->forw = old_info->forw; /* INT_: direct copy */ 1327 new_info->forw = old_info->forw; /* INT_: direct copy */
1328 INT_SET(new_info->back, ARCH_CONVERT, old_blk->blkno); 1328 INT_SET(new_info->back, ARCH_CONVERT, old_blk->blkno);
1329 if (INT_GET(old_info->forw, ARCH_CONVERT)) { 1329 if (INT_GET(old_info->forw, ARCH_CONVERT)) {
1330 error = xfs_da_read_buf(args->trans, args->dp, 1330 error = xfs_da_read_buf(args->trans, args->dp,
1331 INT_GET(old_info->forw, ARCH_CONVERT), -1, &bp, 1331 INT_GET(old_info->forw, ARCH_CONVERT), -1, &bp,
1332 args->whichfork); 1332 args->whichfork);
1333 if (error) 1333 if (error)
1334 return(error); 1334 return(error);
1335 ASSERT(bp != NULL); 1335 ASSERT(bp != NULL);
1336 tmp_info = bp->data; 1336 tmp_info = bp->data;
1337 ASSERT(INT_GET(tmp_info->magic, ARCH_CONVERT) 1337 ASSERT(INT_GET(tmp_info->magic, ARCH_CONVERT)
1338 == INT_GET(old_info->magic, ARCH_CONVERT)); 1338 == INT_GET(old_info->magic, ARCH_CONVERT));
1339 ASSERT(INT_GET(tmp_info->back, ARCH_CONVERT) 1339 ASSERT(INT_GET(tmp_info->back, ARCH_CONVERT)
1340 == old_blk->blkno); 1340 == old_blk->blkno);
1341 INT_SET(tmp_info->back, ARCH_CONVERT, new_blk->blkno); 1341 INT_SET(tmp_info->back, ARCH_CONVERT, new_blk->blkno);
1342 xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1); 1342 xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1);
1343 xfs_da_buf_done(bp); 1343 xfs_da_buf_done(bp);
1344 } 1344 }
1345 INT_SET(old_info->forw, ARCH_CONVERT, new_blk->blkno); 1345 INT_SET(old_info->forw, ARCH_CONVERT, new_blk->blkno);
1346 } 1346 }
1347 1347
1348 xfs_da_log_buf(args->trans, old_blk->bp, 0, sizeof(*tmp_info) - 1); 1348 xfs_da_log_buf(args->trans, old_blk->bp, 0, sizeof(*tmp_info) - 1);
1349 xfs_da_log_buf(args->trans, new_blk->bp, 0, sizeof(*tmp_info) - 1); 1349 xfs_da_log_buf(args->trans, new_blk->bp, 0, sizeof(*tmp_info) - 1);
1350 return(0); 1350 return(0);
1351 } 1351 }
1352 1352
1353 /* 1353 /*
1354 * Compare two intermediate nodes for "order". 1354 * Compare two intermediate nodes for "order".
1355 */ 1355 */
1356 STATIC int 1356 STATIC int
1357 xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp) 1357 xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp)
1358 { 1358 {
1359 xfs_da_intnode_t *node1, *node2; 1359 xfs_da_intnode_t *node1, *node2;
1360 1360
1361 node1 = node1_bp->data; 1361 node1 = node1_bp->data;
1362 node2 = node2_bp->data; 1362 node2 = node2_bp->data;
1363 ASSERT((INT_GET(node1->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC) && 1363 ASSERT((INT_GET(node1->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC) &&
1364 (INT_GET(node2->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC)); 1364 (INT_GET(node2->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC));
1365 if ((INT_GET(node1->hdr.count, ARCH_CONVERT) > 0) && (INT_GET(node2->hdr.count, ARCH_CONVERT) > 0) && 1365 if ((INT_GET(node1->hdr.count, ARCH_CONVERT) > 0) && (INT_GET(node2->hdr.count, ARCH_CONVERT) > 0) &&
1366 ((INT_GET(node2->btree[ 0 ].hashval, ARCH_CONVERT) < 1366 ((INT_GET(node2->btree[ 0 ].hashval, ARCH_CONVERT) <
1367 INT_GET(node1->btree[ 0 ].hashval, ARCH_CONVERT)) || 1367 INT_GET(node1->btree[ 0 ].hashval, ARCH_CONVERT)) ||
1368 (INT_GET(node2->btree[ INT_GET(node2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT) < 1368 (INT_GET(node2->btree[ INT_GET(node2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT) <
1369 INT_GET(node1->btree[ INT_GET(node1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)))) { 1369 INT_GET(node1->btree[ INT_GET(node1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)))) {
1370 return(1); 1370 return(1);
1371 } 1371 }
1372 return(0); 1372 return(0);
1373 } 1373 }
1374 1374
1375 /* 1375 /*
1376 * Pick up the last hashvalue from an intermediate node. 1376 * Pick up the last hashvalue from an intermediate node.
1377 */ 1377 */
1378 STATIC uint 1378 STATIC uint
1379 xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count) 1379 xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count)
1380 { 1380 {
1381 xfs_da_intnode_t *node; 1381 xfs_da_intnode_t *node;
1382 1382
1383 node = bp->data; 1383 node = bp->data;
1384 ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); 1384 ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
1385 if (count) 1385 if (count)
1386 *count = INT_GET(node->hdr.count, ARCH_CONVERT); 1386 *count = INT_GET(node->hdr.count, ARCH_CONVERT);
1387 if (!node->hdr.count) 1387 if (!node->hdr.count)
1388 return(0); 1388 return(0);
1389 return(INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)); 1389 return(INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT));
1390 } 1390 }
1391 1391
1392 /* 1392 /*
1393 * Unlink a block from a doubly linked list of blocks. 1393 * Unlink a block from a doubly linked list of blocks.
1394 */ 1394 */
1395 STATIC int /* error */ 1395 STATIC int /* error */
1396 xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, 1396 xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
1397 xfs_da_state_blk_t *save_blk) 1397 xfs_da_state_blk_t *save_blk)
1398 { 1398 {
1399 xfs_da_blkinfo_t *drop_info, *save_info, *tmp_info; 1399 xfs_da_blkinfo_t *drop_info, *save_info, *tmp_info;
1400 xfs_da_args_t *args; 1400 xfs_da_args_t *args;
1401 xfs_dabuf_t *bp; 1401 xfs_dabuf_t *bp;
1402 int error; 1402 int error;
1403 1403
1404 /* 1404 /*
1405 * Set up environment. 1405 * Set up environment.
1406 */ 1406 */
1407 args = state->args; 1407 args = state->args;
1408 ASSERT(args != NULL); 1408 ASSERT(args != NULL);
1409 save_info = save_blk->bp->data; 1409 save_info = save_blk->bp->data;
1410 drop_info = drop_blk->bp->data; 1410 drop_info = drop_blk->bp->data;
1411 ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC || 1411 ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC ||
1412 save_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) || 1412 save_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) ||
1413 save_blk->magic == XFS_ATTR_LEAF_MAGIC); 1413 save_blk->magic == XFS_ATTR_LEAF_MAGIC);
1414 ASSERT(save_blk->magic == INT_GET(save_info->magic, ARCH_CONVERT)); 1414 ASSERT(save_blk->magic == INT_GET(save_info->magic, ARCH_CONVERT));
1415 ASSERT(drop_blk->magic == INT_GET(drop_info->magic, ARCH_CONVERT)); 1415 ASSERT(drop_blk->magic == INT_GET(drop_info->magic, ARCH_CONVERT));
1416 ASSERT(save_blk->magic == drop_blk->magic); 1416 ASSERT(save_blk->magic == drop_blk->magic);
1417 ASSERT((INT_GET(save_info->forw, ARCH_CONVERT) == drop_blk->blkno) || 1417 ASSERT((INT_GET(save_info->forw, ARCH_CONVERT) == drop_blk->blkno) ||
1418 (INT_GET(save_info->back, ARCH_CONVERT) == drop_blk->blkno)); 1418 (INT_GET(save_info->back, ARCH_CONVERT) == drop_blk->blkno));
1419 ASSERT((INT_GET(drop_info->forw, ARCH_CONVERT) == save_blk->blkno) || 1419 ASSERT((INT_GET(drop_info->forw, ARCH_CONVERT) == save_blk->blkno) ||
1420 (INT_GET(drop_info->back, ARCH_CONVERT) == save_blk->blkno)); 1420 (INT_GET(drop_info->back, ARCH_CONVERT) == save_blk->blkno));
1421 1421
1422 /* 1422 /*
1423 * Unlink the leaf block from the doubly linked chain of leaves. 1423 * Unlink the leaf block from the doubly linked chain of leaves.
1424 */ 1424 */
1425 if (INT_GET(save_info->back, ARCH_CONVERT) == drop_blk->blkno) { 1425 if (INT_GET(save_info->back, ARCH_CONVERT) == drop_blk->blkno) {
1426 save_info->back = drop_info->back; /* INT_: direct copy */ 1426 save_info->back = drop_info->back; /* INT_: direct copy */
1427 if (INT_GET(drop_info->back, ARCH_CONVERT)) { 1427 if (INT_GET(drop_info->back, ARCH_CONVERT)) {
1428 error = xfs_da_read_buf(args->trans, args->dp, 1428 error = xfs_da_read_buf(args->trans, args->dp,
1429 INT_GET(drop_info->back, 1429 INT_GET(drop_info->back,
1430 ARCH_CONVERT), -1, &bp, 1430 ARCH_CONVERT), -1, &bp,
1431 args->whichfork); 1431 args->whichfork);
1432 if (error) 1432 if (error)
1433 return(error); 1433 return(error);
1434 ASSERT(bp != NULL); 1434 ASSERT(bp != NULL);
1435 tmp_info = bp->data; 1435 tmp_info = bp->data;
1436 ASSERT(INT_GET(tmp_info->magic, ARCH_CONVERT) == INT_GET(save_info->magic, ARCH_CONVERT)); 1436 ASSERT(INT_GET(tmp_info->magic, ARCH_CONVERT) == INT_GET(save_info->magic, ARCH_CONVERT));
1437 ASSERT(INT_GET(tmp_info->forw, ARCH_CONVERT) == drop_blk->blkno); 1437 ASSERT(INT_GET(tmp_info->forw, ARCH_CONVERT) == drop_blk->blkno);
1438 INT_SET(tmp_info->forw, ARCH_CONVERT, save_blk->blkno); 1438 INT_SET(tmp_info->forw, ARCH_CONVERT, save_blk->blkno);
1439 xfs_da_log_buf(args->trans, bp, 0, 1439 xfs_da_log_buf(args->trans, bp, 0,
1440 sizeof(*tmp_info) - 1); 1440 sizeof(*tmp_info) - 1);
1441 xfs_da_buf_done(bp); 1441 xfs_da_buf_done(bp);
1442 } 1442 }
1443 } else { 1443 } else {
1444 save_info->forw = drop_info->forw; /* INT_: direct copy */ 1444 save_info->forw = drop_info->forw; /* INT_: direct copy */
1445 if (INT_GET(drop_info->forw, ARCH_CONVERT)) { 1445 if (INT_GET(drop_info->forw, ARCH_CONVERT)) {
1446 error = xfs_da_read_buf(args->trans, args->dp, 1446 error = xfs_da_read_buf(args->trans, args->dp,
1447 INT_GET(drop_info->forw, ARCH_CONVERT), -1, &bp, 1447 INT_GET(drop_info->forw, ARCH_CONVERT), -1, &bp,
1448 args->whichfork); 1448 args->whichfork);
1449 if (error) 1449 if (error)
1450 return(error); 1450 return(error);
1451 ASSERT(bp != NULL); 1451 ASSERT(bp != NULL);
1452 tmp_info = bp->data; 1452 tmp_info = bp->data;
1453 ASSERT(INT_GET(tmp_info->magic, ARCH_CONVERT) 1453 ASSERT(INT_GET(tmp_info->magic, ARCH_CONVERT)
1454 == INT_GET(save_info->magic, ARCH_CONVERT)); 1454 == INT_GET(save_info->magic, ARCH_CONVERT));
1455 ASSERT(INT_GET(tmp_info->back, ARCH_CONVERT) 1455 ASSERT(INT_GET(tmp_info->back, ARCH_CONVERT)
1456 == drop_blk->blkno); 1456 == drop_blk->blkno);
1457 INT_SET(tmp_info->back, ARCH_CONVERT, save_blk->blkno); 1457 INT_SET(tmp_info->back, ARCH_CONVERT, save_blk->blkno);
1458 xfs_da_log_buf(args->trans, bp, 0, 1458 xfs_da_log_buf(args->trans, bp, 0,
1459 sizeof(*tmp_info) - 1); 1459 sizeof(*tmp_info) - 1);
1460 xfs_da_buf_done(bp); 1460 xfs_da_buf_done(bp);
1461 } 1461 }
1462 } 1462 }
1463 1463
1464 xfs_da_log_buf(args->trans, save_blk->bp, 0, sizeof(*save_info) - 1); 1464 xfs_da_log_buf(args->trans, save_blk->bp, 0, sizeof(*save_info) - 1);
1465 return(0); 1465 return(0);
1466 } 1466 }
1467 1467
1468 /* 1468 /*
1469 * Move a path "forward" or "!forward" one block at the current level. 1469 * Move a path "forward" or "!forward" one block at the current level.
1470 * 1470 *
1471 * This routine will adjust a "path" to point to the next block 1471 * This routine will adjust a "path" to point to the next block
1472 * "forward" (higher hashvalues) or "!forward" (lower hashvals) in the 1472 * "forward" (higher hashvalues) or "!forward" (lower hashvals) in the
1473 * Btree, including updating pointers to the intermediate nodes between 1473 * Btree, including updating pointers to the intermediate nodes between
1474 * the new bottom and the root. 1474 * the new bottom and the root.
1475 */ 1475 */
1476 int /* error */ 1476 int /* error */
1477 xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, 1477 xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
1478 int forward, int release, int *result) 1478 int forward, int release, int *result)
1479 { 1479 {
1480 xfs_da_state_blk_t *blk; 1480 xfs_da_state_blk_t *blk;
1481 xfs_da_blkinfo_t *info; 1481 xfs_da_blkinfo_t *info;
1482 xfs_da_intnode_t *node; 1482 xfs_da_intnode_t *node;
1483 xfs_da_args_t *args; 1483 xfs_da_args_t *args;
1484 xfs_dablk_t blkno=0; 1484 xfs_dablk_t blkno=0;
1485 int level, error; 1485 int level, error;
1486 1486
1487 /* 1487 /*
1488 * Roll up the Btree looking for the first block where our 1488 * Roll up the Btree looking for the first block where our
1489 * current index is not at the edge of the block. Note that 1489 * current index is not at the edge of the block. Note that
1490 * we skip the bottom layer because we want the sibling block. 1490 * we skip the bottom layer because we want the sibling block.
1491 */ 1491 */
1492 args = state->args; 1492 args = state->args;
1493 ASSERT(args != NULL); 1493 ASSERT(args != NULL);
1494 ASSERT(path != NULL); 1494 ASSERT(path != NULL);
1495 ASSERT((path->active > 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); 1495 ASSERT((path->active > 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1496 level = (path->active-1) - 1; /* skip bottom layer in path */ 1496 level = (path->active-1) - 1; /* skip bottom layer in path */
1497 for (blk = &path->blk[level]; level >= 0; blk--, level--) { 1497 for (blk = &path->blk[level]; level >= 0; blk--, level--) {
1498 ASSERT(blk->bp != NULL); 1498 ASSERT(blk->bp != NULL);
1499 node = blk->bp->data; 1499 node = blk->bp->data;
1500 ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); 1500 ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
1501 if (forward && (blk->index < INT_GET(node->hdr.count, ARCH_CONVERT)-1)) { 1501 if (forward && (blk->index < INT_GET(node->hdr.count, ARCH_CONVERT)-1)) {
1502 blk->index++; 1502 blk->index++;
1503 blkno = INT_GET(node->btree[ blk->index ].before, ARCH_CONVERT); 1503 blkno = INT_GET(node->btree[ blk->index ].before, ARCH_CONVERT);
1504 break; 1504 break;
1505 } else if (!forward && (blk->index > 0)) { 1505 } else if (!forward && (blk->index > 0)) {
1506 blk->index--; 1506 blk->index--;
1507 blkno = INT_GET(node->btree[ blk->index ].before, ARCH_CONVERT); 1507 blkno = INT_GET(node->btree[ blk->index ].before, ARCH_CONVERT);
1508 break; 1508 break;
1509 } 1509 }
1510 } 1510 }
1511 if (level < 0) { 1511 if (level < 0) {
1512 *result = XFS_ERROR(ENOENT); /* we're out of our tree */ 1512 *result = XFS_ERROR(ENOENT); /* we're out of our tree */
1513 ASSERT(args->oknoent); 1513 ASSERT(args->oknoent);
1514 return(0); 1514 return(0);
1515 } 1515 }
1516 1516
1517 /* 1517 /*
1518 * Roll down the edge of the subtree until we reach the 1518 * Roll down the edge of the subtree until we reach the
1519 * same depth we were at originally. 1519 * same depth we were at originally.
1520 */ 1520 */
1521 for (blk++, level++; level < path->active; blk++, level++) { 1521 for (blk++, level++; level < path->active; blk++, level++) {
1522 /* 1522 /*
1523 * Release the old block. 1523 * Release the old block.
1524 * (if it's dirty, trans won't actually let go) 1524 * (if it's dirty, trans won't actually let go)
1525 */ 1525 */
1526 if (release) 1526 if (release)
1527 xfs_da_brelse(args->trans, blk->bp); 1527 xfs_da_brelse(args->trans, blk->bp);
1528 1528
1529 /* 1529 /*
1530 * Read the next child block. 1530 * Read the next child block.
1531 */ 1531 */
1532 blk->blkno = blkno; 1532 blk->blkno = blkno;
1533 error = xfs_da_read_buf(args->trans, args->dp, blkno, -1, 1533 error = xfs_da_read_buf(args->trans, args->dp, blkno, -1,
1534 &blk->bp, args->whichfork); 1534 &blk->bp, args->whichfork);
1535 if (error) 1535 if (error)
1536 return(error); 1536 return(error);
1537 ASSERT(blk->bp != NULL); 1537 ASSERT(blk->bp != NULL);
1538 info = blk->bp->data; 1538 info = blk->bp->data;
1539 ASSERT(INT_GET(info->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC || 1539 ASSERT(INT_GET(info->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC ||
1540 INT_GET(info->magic, ARCH_CONVERT) == XFS_DIRX_LEAF_MAGIC(state->mp) || 1540 INT_GET(info->magic, ARCH_CONVERT) == XFS_DIRX_LEAF_MAGIC(state->mp) ||
1541 INT_GET(info->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC); 1541 INT_GET(info->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC);
1542 blk->magic = INT_GET(info->magic, ARCH_CONVERT); 1542 blk->magic = INT_GET(info->magic, ARCH_CONVERT);
1543 if (INT_GET(info->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC) { 1543 if (INT_GET(info->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC) {
1544 node = (xfs_da_intnode_t *)info; 1544 node = (xfs_da_intnode_t *)info;
1545 blk->hashval = INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); 1545 blk->hashval = INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
1546 if (forward) 1546 if (forward)
1547 blk->index = 0; 1547 blk->index = 0;
1548 else 1548 else
1549 blk->index = INT_GET(node->hdr.count, ARCH_CONVERT)-1; 1549 blk->index = INT_GET(node->hdr.count, ARCH_CONVERT)-1;
1550 blkno = INT_GET(node->btree[ blk->index ].before, ARCH_CONVERT); 1550 blkno = INT_GET(node->btree[ blk->index ].before, ARCH_CONVERT);
1551 } else { 1551 } else {
1552 ASSERT(level == path->active-1); 1552 ASSERT(level == path->active-1);
1553 blk->index = 0; 1553 blk->index = 0;
1554 switch(blk->magic) { 1554 switch(blk->magic) {
1555 case XFS_ATTR_LEAF_MAGIC: 1555 case XFS_ATTR_LEAF_MAGIC:
1556 blk->hashval = xfs_attr_leaf_lasthash(blk->bp, 1556 blk->hashval = xfs_attr_leaf_lasthash(blk->bp,
1557 NULL); 1557 NULL);
1558 break; 1558 break;
1559 case XFS_DIR_LEAF_MAGIC: 1559 case XFS_DIR_LEAF_MAGIC:
1560 ASSERT(XFS_DIR_IS_V1(state->mp)); 1560 ASSERT(XFS_DIR_IS_V1(state->mp));
1561 blk->hashval = xfs_dir_leaf_lasthash(blk->bp, 1561 blk->hashval = xfs_dir_leaf_lasthash(blk->bp,
1562 NULL); 1562 NULL);
1563 break; 1563 break;
1564 case XFS_DIR2_LEAFN_MAGIC: 1564 case XFS_DIR2_LEAFN_MAGIC:
1565 ASSERT(XFS_DIR_IS_V2(state->mp)); 1565 ASSERT(XFS_DIR_IS_V2(state->mp));
1566 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, 1566 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp,
1567 NULL); 1567 NULL);
1568 break; 1568 break;
1569 default: 1569 default:
1570 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC || 1570 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC ||
1571 blk->magic == 1571 blk->magic ==
1572 XFS_DIRX_LEAF_MAGIC(state->mp)); 1572 XFS_DIRX_LEAF_MAGIC(state->mp));
1573 break; 1573 break;
1574 } 1574 }
1575 } 1575 }
1576 } 1576 }
1577 *result = 0; 1577 *result = 0;
1578 return(0); 1578 return(0);
1579 } 1579 }
1580 1580
1581 1581
1582 /*======================================================================== 1582 /*========================================================================
1583 * Utility routines. 1583 * Utility routines.
1584 *========================================================================*/ 1584 *========================================================================*/
1585 1585
1586 /* 1586 /*
1587 * Implement a simple hash on a character string. 1587 * Implement a simple hash on a character string.
1588 * Rotate the hash value by 7 bits, then XOR each character in. 1588 * Rotate the hash value by 7 bits, then XOR each character in.
1589 * This is implemented with some source-level loop unrolling. 1589 * This is implemented with some source-level loop unrolling.
1590 */ 1590 */
1591 xfs_dahash_t 1591 xfs_dahash_t
1592 xfs_da_hashname(const uchar_t *name, int namelen) 1592 xfs_da_hashname(const uchar_t *name, int namelen)
1593 { 1593 {
1594 xfs_dahash_t hash; 1594 xfs_dahash_t hash;
1595 1595
1596 /* 1596 /*
1597 * Do four characters at a time as long as we can. 1597 * Do four characters at a time as long as we can.
1598 */ 1598 */
1599 for (hash = 0; namelen >= 4; namelen -= 4, name += 4) 1599 for (hash = 0; namelen >= 4; namelen -= 4, name += 4)
1600 hash = (name[0] << 21) ^ (name[1] << 14) ^ (name[2] << 7) ^ 1600 hash = (name[0] << 21) ^ (name[1] << 14) ^ (name[2] << 7) ^
1601 (name[3] << 0) ^ rol32(hash, 7 * 4); 1601 (name[3] << 0) ^ rol32(hash, 7 * 4);
1602 1602
1603 /* 1603 /*
1604 * Now do the rest of the characters. 1604 * Now do the rest of the characters.
1605 */ 1605 */
1606 switch (namelen) { 1606 switch (namelen) {
1607 case 3: 1607 case 3:
1608 return (name[0] << 14) ^ (name[1] << 7) ^ (name[2] << 0) ^ 1608 return (name[0] << 14) ^ (name[1] << 7) ^ (name[2] << 0) ^
1609 rol32(hash, 7 * 3); 1609 rol32(hash, 7 * 3);
1610 case 2: 1610 case 2:
1611 return (name[0] << 7) ^ (name[1] << 0) ^ rol32(hash, 7 * 2); 1611 return (name[0] << 7) ^ (name[1] << 0) ^ rol32(hash, 7 * 2);
1612 case 1: 1612 case 1:
1613 return (name[0] << 0) ^ rol32(hash, 7 * 1); 1613 return (name[0] << 0) ^ rol32(hash, 7 * 1);
1614 default: /* case 0: */ 1614 default: /* case 0: */
1615 return hash; 1615 return hash;
1616 } 1616 }
1617 } 1617 }
1618 1618
1619 /* 1619 /*
1620 * Add a block to the btree ahead of the file. 1620 * Add a block to the btree ahead of the file.
1621 * Return the new block number to the caller. 1621 * Return the new block number to the caller.
1622 */ 1622 */
1623 int 1623 int
1624 xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) 1624 xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1625 { 1625 {
1626 xfs_fileoff_t bno, b; 1626 xfs_fileoff_t bno, b;
1627 xfs_bmbt_irec_t map; 1627 xfs_bmbt_irec_t map;
1628 xfs_bmbt_irec_t *mapp; 1628 xfs_bmbt_irec_t *mapp;
1629 xfs_inode_t *dp; 1629 xfs_inode_t *dp;
1630 int nmap, error, w, count, c, got, i, mapi; 1630 int nmap, error, w, count, c, got, i, mapi;
1631 xfs_fsize_t size; 1631 xfs_fsize_t size;
1632 xfs_trans_t *tp; 1632 xfs_trans_t *tp;
1633 xfs_mount_t *mp; 1633 xfs_mount_t *mp;
1634 1634
1635 dp = args->dp; 1635 dp = args->dp;
1636 mp = dp->i_mount; 1636 mp = dp->i_mount;
1637 w = args->whichfork; 1637 w = args->whichfork;
1638 tp = args->trans; 1638 tp = args->trans;
1639 /* 1639 /*
1640 * For new directories adjust the file offset and block count. 1640 * For new directories adjust the file offset and block count.
1641 */ 1641 */
1642 if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) { 1642 if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) {
1643 bno = mp->m_dirleafblk; 1643 bno = mp->m_dirleafblk;
1644 count = mp->m_dirblkfsbs; 1644 count = mp->m_dirblkfsbs;
1645 } else { 1645 } else {
1646 bno = 0; 1646 bno = 0;
1647 count = 1; 1647 count = 1;
1648 } 1648 }
1649 /* 1649 /*
1650 * Find a spot in the file space to put the new block. 1650 * Find a spot in the file space to put the new block.
1651 */ 1651 */
1652 if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) { 1652 if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) {
1653 return error; 1653 return error;
1654 } 1654 }
1655 if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) 1655 if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
1656 ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk); 1656 ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk);
1657 /* 1657 /*
1658 * Try mapping it in one filesystem block. 1658 * Try mapping it in one filesystem block.
1659 */ 1659 */
1660 nmap = 1; 1660 nmap = 1;
1661 ASSERT(args->firstblock != NULL); 1661 ASSERT(args->firstblock != NULL);
1662 if ((error = xfs_bmapi(tp, dp, bno, count, 1662 if ((error = xfs_bmapi(tp, dp, bno, count,
1663 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA| 1663 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|
1664 XFS_BMAPI_CONTIG, 1664 XFS_BMAPI_CONTIG,
1665 args->firstblock, args->total, &map, &nmap, 1665 args->firstblock, args->total, &map, &nmap,
1666 args->flist))) { 1666 args->flist))) {
1667 return error; 1667 return error;
1668 } 1668 }
1669 ASSERT(nmap <= 1); 1669 ASSERT(nmap <= 1);
1670 if (nmap == 1) { 1670 if (nmap == 1) {
1671 mapp = &map; 1671 mapp = &map;
1672 mapi = 1; 1672 mapi = 1;
1673 } 1673 }
1674 /* 1674 /*
1675 * If we didn't get it and the block might work if fragmented, 1675 * If we didn't get it and the block might work if fragmented,
1676 * try without the CONTIG flag. Loop until we get it all. 1676 * try without the CONTIG flag. Loop until we get it all.
1677 */ 1677 */
1678 else if (nmap == 0 && count > 1) { 1678 else if (nmap == 0 && count > 1) {
1679 mapp = kmem_alloc(sizeof(*mapp) * count, KM_SLEEP); 1679 mapp = kmem_alloc(sizeof(*mapp) * count, KM_SLEEP);
1680 for (b = bno, mapi = 0; b < bno + count; ) { 1680 for (b = bno, mapi = 0; b < bno + count; ) {
1681 nmap = MIN(XFS_BMAP_MAX_NMAP, count); 1681 nmap = MIN(XFS_BMAP_MAX_NMAP, count);
1682 c = (int)(bno + count - b); 1682 c = (int)(bno + count - b);
1683 if ((error = xfs_bmapi(tp, dp, b, c, 1683 if ((error = xfs_bmapi(tp, dp, b, c,
1684 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE| 1684 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|
1685 XFS_BMAPI_METADATA, 1685 XFS_BMAPI_METADATA,
1686 args->firstblock, args->total, 1686 args->firstblock, args->total,
1687 &mapp[mapi], &nmap, args->flist))) { 1687 &mapp[mapi], &nmap, args->flist))) {
1688 kmem_free(mapp, sizeof(*mapp) * count); 1688 kmem_free(mapp, sizeof(*mapp) * count);
1689 return error; 1689 return error;
1690 } 1690 }
1691 if (nmap < 1) 1691 if (nmap < 1)
1692 break; 1692 break;
1693 mapi += nmap; 1693 mapi += nmap;
1694 b = mapp[mapi - 1].br_startoff + 1694 b = mapp[mapi - 1].br_startoff +
1695 mapp[mapi - 1].br_blockcount; 1695 mapp[mapi - 1].br_blockcount;
1696 } 1696 }
1697 } else { 1697 } else {
1698 mapi = 0; 1698 mapi = 0;
1699 mapp = NULL; 1699 mapp = NULL;
1700 } 1700 }
1701 /* 1701 /*
1702 * Count the blocks we got, make sure it matches the total. 1702 * Count the blocks we got, make sure it matches the total.
1703 */ 1703 */
1704 for (i = 0, got = 0; i < mapi; i++) 1704 for (i = 0, got = 0; i < mapi; i++)
1705 got += mapp[i].br_blockcount; 1705 got += mapp[i].br_blockcount;
1706 if (got != count || mapp[0].br_startoff != bno || 1706 if (got != count || mapp[0].br_startoff != bno ||
1707 mapp[mapi - 1].br_startoff + mapp[mapi - 1].br_blockcount != 1707 mapp[mapi - 1].br_startoff + mapp[mapi - 1].br_blockcount !=
1708 bno + count) { 1708 bno + count) {
1709 if (mapp != &map) 1709 if (mapp != &map)
1710 kmem_free(mapp, sizeof(*mapp) * count); 1710 kmem_free(mapp, sizeof(*mapp) * count);
1711 return XFS_ERROR(ENOSPC); 1711 return XFS_ERROR(ENOSPC);
1712 } 1712 }
1713 if (mapp != &map) 1713 if (mapp != &map)
1714 kmem_free(mapp, sizeof(*mapp) * count); 1714 kmem_free(mapp, sizeof(*mapp) * count);
1715 *new_blkno = (xfs_dablk_t)bno; 1715 *new_blkno = (xfs_dablk_t)bno;
1716 /* 1716 /*
1717 * For version 1 directories, adjust the file size if it changed. 1717 * For version 1 directories, adjust the file size if it changed.
1718 */ 1718 */
1719 if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) { 1719 if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) {
1720 ASSERT(mapi == 1); 1720 ASSERT(mapi == 1);
1721 if ((error = xfs_bmap_last_offset(tp, dp, &bno, w))) 1721 if ((error = xfs_bmap_last_offset(tp, dp, &bno, w)))
1722 return error; 1722 return error;
1723 size = XFS_FSB_TO_B(mp, bno); 1723 size = XFS_FSB_TO_B(mp, bno);
1724 if (size != dp->i_d.di_size) { 1724 if (size != dp->i_d.di_size) {
1725 dp->i_d.di_size = size; 1725 dp->i_d.di_size = size;
1726 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); 1726 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
1727 } 1727 }
1728 } 1728 }
1729 return 0; 1729 return 0;
1730 } 1730 }
1731 1731
1732 /* 1732 /*
1733 * Ick. We need to always be able to remove a btree block, even 1733 * Ick. We need to always be able to remove a btree block, even
1734 * if there's no space reservation because the filesystem is full. 1734 * if there's no space reservation because the filesystem is full.
1735 * This is called if xfs_bunmapi on a btree block fails due to ENOSPC. 1735 * This is called if xfs_bunmapi on a btree block fails due to ENOSPC.
1736 * It swaps the target block with the last block in the file. The 1736 * It swaps the target block with the last block in the file. The
1737 * last block in the file can always be removed since it can't cause 1737 * last block in the file can always be removed since it can't cause
1738 * a bmap btree split to do that. 1738 * a bmap btree split to do that.
1739 */ 1739 */
1740 STATIC int 1740 STATIC int
1741 xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, 1741 xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
1742 xfs_dabuf_t **dead_bufp) 1742 xfs_dabuf_t **dead_bufp)
1743 { 1743 {
1744 xfs_dablk_t dead_blkno, last_blkno, sib_blkno, par_blkno; 1744 xfs_dablk_t dead_blkno, last_blkno, sib_blkno, par_blkno;
1745 xfs_dabuf_t *dead_buf, *last_buf, *sib_buf, *par_buf; 1745 xfs_dabuf_t *dead_buf, *last_buf, *sib_buf, *par_buf;
1746 xfs_fileoff_t lastoff; 1746 xfs_fileoff_t lastoff;
1747 xfs_inode_t *ip; 1747 xfs_inode_t *ip;
1748 xfs_trans_t *tp; 1748 xfs_trans_t *tp;
1749 xfs_mount_t *mp; 1749 xfs_mount_t *mp;
1750 int error, w, entno, level, dead_level; 1750 int error, w, entno, level, dead_level;
1751 xfs_da_blkinfo_t *dead_info, *sib_info; 1751 xfs_da_blkinfo_t *dead_info, *sib_info;
1752 xfs_da_intnode_t *par_node, *dead_node; 1752 xfs_da_intnode_t *par_node, *dead_node;
1753 xfs_dir_leafblock_t *dead_leaf; 1753 xfs_dir_leafblock_t *dead_leaf;
1754 xfs_dir2_leaf_t *dead_leaf2; 1754 xfs_dir2_leaf_t *dead_leaf2;
1755 xfs_dahash_t dead_hash; 1755 xfs_dahash_t dead_hash;
1756 1756
1757 dead_buf = *dead_bufp; 1757 dead_buf = *dead_bufp;
1758 dead_blkno = *dead_blknop; 1758 dead_blkno = *dead_blknop;
1759 tp = args->trans; 1759 tp = args->trans;
1760 ip = args->dp; 1760 ip = args->dp;
1761 w = args->whichfork; 1761 w = args->whichfork;
1762 ASSERT(w == XFS_DATA_FORK); 1762 ASSERT(w == XFS_DATA_FORK);
1763 mp = ip->i_mount; 1763 mp = ip->i_mount;
1764 if (XFS_DIR_IS_V2(mp)) { 1764 if (XFS_DIR_IS_V2(mp)) {
1765 lastoff = mp->m_dirfreeblk; 1765 lastoff = mp->m_dirfreeblk;
1766 error = xfs_bmap_last_before(tp, ip, &lastoff, w); 1766 error = xfs_bmap_last_before(tp, ip, &lastoff, w);
1767 } else 1767 } else
1768 error = xfs_bmap_last_offset(tp, ip, &lastoff, w); 1768 error = xfs_bmap_last_offset(tp, ip, &lastoff, w);
1769 if (error) 1769 if (error)
1770 return error; 1770 return error;
1771 if (unlikely(lastoff == 0)) { 1771 if (unlikely(lastoff == 0)) {
1772 XFS_ERROR_REPORT("xfs_da_swap_lastblock(1)", XFS_ERRLEVEL_LOW, 1772 XFS_ERROR_REPORT("xfs_da_swap_lastblock(1)", XFS_ERRLEVEL_LOW,
1773 mp); 1773 mp);
1774 return XFS_ERROR(EFSCORRUPTED); 1774 return XFS_ERROR(EFSCORRUPTED);
1775 } 1775 }
1776 /* 1776 /*
1777 * Read the last block in the btree space. 1777 * Read the last block in the btree space.
1778 */ 1778 */
1779 last_blkno = (xfs_dablk_t)lastoff - mp->m_dirblkfsbs; 1779 last_blkno = (xfs_dablk_t)lastoff - mp->m_dirblkfsbs;
1780 if ((error = xfs_da_read_buf(tp, ip, last_blkno, -1, &last_buf, w))) 1780 if ((error = xfs_da_read_buf(tp, ip, last_blkno, -1, &last_buf, w)))
1781 return error; 1781 return error;
1782 /* 1782 /*
1783 * Copy the last block into the dead buffer and log it. 1783 * Copy the last block into the dead buffer and log it.
1784 */ 1784 */
1785 memcpy(dead_buf->data, last_buf->data, mp->m_dirblksize); 1785 memcpy(dead_buf->data, last_buf->data, mp->m_dirblksize);
1786 xfs_da_log_buf(tp, dead_buf, 0, mp->m_dirblksize - 1); 1786 xfs_da_log_buf(tp, dead_buf, 0, mp->m_dirblksize - 1);
1787 dead_info = dead_buf->data; 1787 dead_info = dead_buf->data;
1788 /* 1788 /*
1789 * Get values from the moved block. 1789 * Get values from the moved block.
1790 */ 1790 */
1791 if (INT_GET(dead_info->magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC) { 1791 if (INT_GET(dead_info->magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC) {
1792 ASSERT(XFS_DIR_IS_V1(mp)); 1792 ASSERT(XFS_DIR_IS_V1(mp));
1793 dead_leaf = (xfs_dir_leafblock_t *)dead_info; 1793 dead_leaf = (xfs_dir_leafblock_t *)dead_info;
1794 dead_level = 0; 1794 dead_level = 0;
1795 dead_hash = 1795 dead_hash =
1796 INT_GET(dead_leaf->entries[INT_GET(dead_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT); 1796 INT_GET(dead_leaf->entries[INT_GET(dead_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT);
1797 } else if (INT_GET(dead_info->magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC) { 1797 } else if (INT_GET(dead_info->magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC) {
1798 ASSERT(XFS_DIR_IS_V2(mp)); 1798 ASSERT(XFS_DIR_IS_V2(mp));
1799 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; 1799 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
1800 dead_level = 0; 1800 dead_level = 0;
1801 dead_hash = INT_GET(dead_leaf2->ents[INT_GET(dead_leaf2->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT); 1801 dead_hash = INT_GET(dead_leaf2->ents[INT_GET(dead_leaf2->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT);
1802 } else { 1802 } else {
1803 ASSERT(INT_GET(dead_info->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC); 1803 ASSERT(INT_GET(dead_info->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
1804 dead_node = (xfs_da_intnode_t *)dead_info; 1804 dead_node = (xfs_da_intnode_t *)dead_info;
1805 dead_level = INT_GET(dead_node->hdr.level, ARCH_CONVERT); 1805 dead_level = INT_GET(dead_node->hdr.level, ARCH_CONVERT);
1806 dead_hash = INT_GET(dead_node->btree[INT_GET(dead_node->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT); 1806 dead_hash = INT_GET(dead_node->btree[INT_GET(dead_node->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT);
1807 } 1807 }
1808 sib_buf = par_buf = NULL; 1808 sib_buf = par_buf = NULL;
1809 /* 1809 /*
1810 * If the moved block has a left sibling, fix up the pointers. 1810 * If the moved block has a left sibling, fix up the pointers.
1811 */ 1811 */
1812 if ((sib_blkno = INT_GET(dead_info->back, ARCH_CONVERT))) { 1812 if ((sib_blkno = INT_GET(dead_info->back, ARCH_CONVERT))) {
1813 if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w))) 1813 if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w)))
1814 goto done; 1814 goto done;
1815 sib_info = sib_buf->data; 1815 sib_info = sib_buf->data;
1816 if (unlikely( 1816 if (unlikely(
1817 INT_GET(sib_info->forw, ARCH_CONVERT) != last_blkno || 1817 INT_GET(sib_info->forw, ARCH_CONVERT) != last_blkno ||
1818 INT_GET(sib_info->magic, ARCH_CONVERT) != INT_GET(dead_info->magic, ARCH_CONVERT))) { 1818 INT_GET(sib_info->magic, ARCH_CONVERT) != INT_GET(dead_info->magic, ARCH_CONVERT))) {
1819 XFS_ERROR_REPORT("xfs_da_swap_lastblock(2)", 1819 XFS_ERROR_REPORT("xfs_da_swap_lastblock(2)",
1820 XFS_ERRLEVEL_LOW, mp); 1820 XFS_ERRLEVEL_LOW, mp);
1821 error = XFS_ERROR(EFSCORRUPTED); 1821 error = XFS_ERROR(EFSCORRUPTED);
1822 goto done; 1822 goto done;
1823 } 1823 }
1824 INT_SET(sib_info->forw, ARCH_CONVERT, dead_blkno); 1824 INT_SET(sib_info->forw, ARCH_CONVERT, dead_blkno);
1825 xfs_da_log_buf(tp, sib_buf, 1825 xfs_da_log_buf(tp, sib_buf,
1826 XFS_DA_LOGRANGE(sib_info, &sib_info->forw, 1826 XFS_DA_LOGRANGE(sib_info, &sib_info->forw,
1827 sizeof(sib_info->forw))); 1827 sizeof(sib_info->forw)));
1828 xfs_da_buf_done(sib_buf); 1828 xfs_da_buf_done(sib_buf);
1829 sib_buf = NULL; 1829 sib_buf = NULL;
1830 } 1830 }
1831 /* 1831 /*
1832 * If the moved block has a right sibling, fix up the pointers. 1832 * If the moved block has a right sibling, fix up the pointers.
1833 */ 1833 */
1834 if ((sib_blkno = INT_GET(dead_info->forw, ARCH_CONVERT))) { 1834 if ((sib_blkno = INT_GET(dead_info->forw, ARCH_CONVERT))) {
1835 if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w))) 1835 if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w)))
1836 goto done; 1836 goto done;
1837 sib_info = sib_buf->data; 1837 sib_info = sib_buf->data;
1838 if (unlikely( 1838 if (unlikely(
1839 INT_GET(sib_info->back, ARCH_CONVERT) != last_blkno 1839 INT_GET(sib_info->back, ARCH_CONVERT) != last_blkno
1840 || INT_GET(sib_info->magic, ARCH_CONVERT) 1840 || INT_GET(sib_info->magic, ARCH_CONVERT)
1841 != INT_GET(dead_info->magic, ARCH_CONVERT))) { 1841 != INT_GET(dead_info->magic, ARCH_CONVERT))) {
1842 XFS_ERROR_REPORT("xfs_da_swap_lastblock(3)", 1842 XFS_ERROR_REPORT("xfs_da_swap_lastblock(3)",
1843 XFS_ERRLEVEL_LOW, mp); 1843 XFS_ERRLEVEL_LOW, mp);
1844 error = XFS_ERROR(EFSCORRUPTED); 1844 error = XFS_ERROR(EFSCORRUPTED);
1845 goto done; 1845 goto done;
1846 } 1846 }
1847 INT_SET(sib_info->back, ARCH_CONVERT, dead_blkno); 1847 INT_SET(sib_info->back, ARCH_CONVERT, dead_blkno);
1848 xfs_da_log_buf(tp, sib_buf, 1848 xfs_da_log_buf(tp, sib_buf,
1849 XFS_DA_LOGRANGE(sib_info, &sib_info->back, 1849 XFS_DA_LOGRANGE(sib_info, &sib_info->back,
1850 sizeof(sib_info->back))); 1850 sizeof(sib_info->back)));
1851 xfs_da_buf_done(sib_buf); 1851 xfs_da_buf_done(sib_buf);
1852 sib_buf = NULL; 1852 sib_buf = NULL;
1853 } 1853 }
1854 par_blkno = XFS_DIR_IS_V1(mp) ? 0 : mp->m_dirleafblk; 1854 par_blkno = XFS_DIR_IS_V1(mp) ? 0 : mp->m_dirleafblk;
1855 level = -1; 1855 level = -1;
1856 /* 1856 /*
1857 * Walk down the tree looking for the parent of the moved block. 1857 * Walk down the tree looking for the parent of the moved block.
1858 */ 1858 */
1859 for (;;) { 1859 for (;;) {
1860 if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w))) 1860 if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w)))
1861 goto done; 1861 goto done;
1862 par_node = par_buf->data; 1862 par_node = par_buf->data;
1863 if (unlikely( 1863 if (unlikely(
1864 INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC || 1864 INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC ||
1865 (level >= 0 && level != INT_GET(par_node->hdr.level, ARCH_CONVERT) + 1))) { 1865 (level >= 0 && level != INT_GET(par_node->hdr.level, ARCH_CONVERT) + 1))) {
1866 XFS_ERROR_REPORT("xfs_da_swap_lastblock(4)", 1866 XFS_ERROR_REPORT("xfs_da_swap_lastblock(4)",
1867 XFS_ERRLEVEL_LOW, mp); 1867 XFS_ERRLEVEL_LOW, mp);
1868 error = XFS_ERROR(EFSCORRUPTED); 1868 error = XFS_ERROR(EFSCORRUPTED);
1869 goto done; 1869 goto done;
1870 } 1870 }
1871 level = INT_GET(par_node->hdr.level, ARCH_CONVERT); 1871 level = INT_GET(par_node->hdr.level, ARCH_CONVERT);
1872 for (entno = 0; 1872 for (entno = 0;
1873 entno < INT_GET(par_node->hdr.count, ARCH_CONVERT) && 1873 entno < INT_GET(par_node->hdr.count, ARCH_CONVERT) &&
1874 INT_GET(par_node->btree[entno].hashval, ARCH_CONVERT) < dead_hash; 1874 INT_GET(par_node->btree[entno].hashval, ARCH_CONVERT) < dead_hash;
1875 entno++) 1875 entno++)
1876 continue; 1876 continue;
1877 if (unlikely(entno == INT_GET(par_node->hdr.count, ARCH_CONVERT))) { 1877 if (unlikely(entno == INT_GET(par_node->hdr.count, ARCH_CONVERT))) {
1878 XFS_ERROR_REPORT("xfs_da_swap_lastblock(5)", 1878 XFS_ERROR_REPORT("xfs_da_swap_lastblock(5)",
1879 XFS_ERRLEVEL_LOW, mp); 1879 XFS_ERRLEVEL_LOW, mp);
1880 error = XFS_ERROR(EFSCORRUPTED); 1880 error = XFS_ERROR(EFSCORRUPTED);
1881 goto done; 1881 goto done;
1882 } 1882 }
1883 par_blkno = INT_GET(par_node->btree[entno].before, ARCH_CONVERT); 1883 par_blkno = INT_GET(par_node->btree[entno].before, ARCH_CONVERT);
1884 if (level == dead_level + 1) 1884 if (level == dead_level + 1)
1885 break; 1885 break;
1886 xfs_da_brelse(tp, par_buf); 1886 xfs_da_brelse(tp, par_buf);
1887 par_buf = NULL; 1887 par_buf = NULL;
1888 } 1888 }
1889 /* 1889 /*
1890 * We're in the right parent block. 1890 * We're in the right parent block.
1891 * Look for the right entry. 1891 * Look for the right entry.
1892 */ 1892 */
1893 for (;;) { 1893 for (;;) {
1894 for (; 1894 for (;
1895 entno < INT_GET(par_node->hdr.count, ARCH_CONVERT) && 1895 entno < INT_GET(par_node->hdr.count, ARCH_CONVERT) &&
1896 INT_GET(par_node->btree[entno].before, ARCH_CONVERT) != last_blkno; 1896 INT_GET(par_node->btree[entno].before, ARCH_CONVERT) != last_blkno;
1897 entno++) 1897 entno++)
1898 continue; 1898 continue;
1899 if (entno < INT_GET(par_node->hdr.count, ARCH_CONVERT)) 1899 if (entno < INT_GET(par_node->hdr.count, ARCH_CONVERT))
1900 break; 1900 break;
1901 par_blkno = INT_GET(par_node->hdr.info.forw, ARCH_CONVERT); 1901 par_blkno = INT_GET(par_node->hdr.info.forw, ARCH_CONVERT);
1902 xfs_da_brelse(tp, par_buf); 1902 xfs_da_brelse(tp, par_buf);
1903 par_buf = NULL; 1903 par_buf = NULL;
1904 if (unlikely(par_blkno == 0)) { 1904 if (unlikely(par_blkno == 0)) {
1905 XFS_ERROR_REPORT("xfs_da_swap_lastblock(6)", 1905 XFS_ERROR_REPORT("xfs_da_swap_lastblock(6)",
1906 XFS_ERRLEVEL_LOW, mp); 1906 XFS_ERRLEVEL_LOW, mp);
1907 error = XFS_ERROR(EFSCORRUPTED); 1907 error = XFS_ERROR(EFSCORRUPTED);
1908 goto done; 1908 goto done;
1909 } 1909 }
1910 if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w))) 1910 if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w)))
1911 goto done; 1911 goto done;
1912 par_node = par_buf->data; 1912 par_node = par_buf->data;
1913 if (unlikely( 1913 if (unlikely(
1914 INT_GET(par_node->hdr.level, ARCH_CONVERT) != level || 1914 INT_GET(par_node->hdr.level, ARCH_CONVERT) != level ||
1915 INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC)) { 1915 INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC)) {
1916 XFS_ERROR_REPORT("xfs_da_swap_lastblock(7)", 1916 XFS_ERROR_REPORT("xfs_da_swap_lastblock(7)",
1917 XFS_ERRLEVEL_LOW, mp); 1917 XFS_ERRLEVEL_LOW, mp);
1918 error = XFS_ERROR(EFSCORRUPTED); 1918 error = XFS_ERROR(EFSCORRUPTED);
1919 goto done; 1919 goto done;
1920 } 1920 }
1921 entno = 0; 1921 entno = 0;
1922 } 1922 }
1923 /* 1923 /*
1924 * Update the parent entry pointing to the moved block. 1924 * Update the parent entry pointing to the moved block.
1925 */ 1925 */
1926 INT_SET(par_node->btree[entno].before, ARCH_CONVERT, dead_blkno); 1926 INT_SET(par_node->btree[entno].before, ARCH_CONVERT, dead_blkno);
1927 xfs_da_log_buf(tp, par_buf, 1927 xfs_da_log_buf(tp, par_buf,
1928 XFS_DA_LOGRANGE(par_node, &par_node->btree[entno].before, 1928 XFS_DA_LOGRANGE(par_node, &par_node->btree[entno].before,
1929 sizeof(par_node->btree[entno].before))); 1929 sizeof(par_node->btree[entno].before)));
1930 xfs_da_buf_done(par_buf); 1930 xfs_da_buf_done(par_buf);
1931 xfs_da_buf_done(dead_buf); 1931 xfs_da_buf_done(dead_buf);
1932 *dead_blknop = last_blkno; 1932 *dead_blknop = last_blkno;
1933 *dead_bufp = last_buf; 1933 *dead_bufp = last_buf;
1934 return 0; 1934 return 0;
1935 done: 1935 done:
1936 if (par_buf) 1936 if (par_buf)
1937 xfs_da_brelse(tp, par_buf); 1937 xfs_da_brelse(tp, par_buf);
1938 if (sib_buf) 1938 if (sib_buf)
1939 xfs_da_brelse(tp, sib_buf); 1939 xfs_da_brelse(tp, sib_buf);
1940 xfs_da_brelse(tp, last_buf); 1940 xfs_da_brelse(tp, last_buf);
1941 return error; 1941 return error;
1942 } 1942 }
1943 1943
1944 /* 1944 /*
1945 * Remove a btree block from a directory or attribute. 1945 * Remove a btree block from a directory or attribute.
1946 */ 1946 */
1947 int 1947 int
1948 xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, 1948 xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
1949 xfs_dabuf_t *dead_buf) 1949 xfs_dabuf_t *dead_buf)
1950 { 1950 {
1951 xfs_inode_t *dp; 1951 xfs_inode_t *dp;
1952 int done, error, w, count; 1952 int done, error, w, count;
1953 xfs_fileoff_t bno; 1953 xfs_fileoff_t bno;
1954 xfs_fsize_t size; 1954 xfs_fsize_t size;
1955 xfs_trans_t *tp; 1955 xfs_trans_t *tp;
1956 xfs_mount_t *mp; 1956 xfs_mount_t *mp;
1957 1957
1958 dp = args->dp; 1958 dp = args->dp;
1959 w = args->whichfork; 1959 w = args->whichfork;
1960 tp = args->trans; 1960 tp = args->trans;
1961 mp = dp->i_mount; 1961 mp = dp->i_mount;
1962 if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) 1962 if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
1963 count = mp->m_dirblkfsbs; 1963 count = mp->m_dirblkfsbs;
1964 else 1964 else
1965 count = 1; 1965 count = 1;
1966 for (;;) { 1966 for (;;) {
1967 /* 1967 /*
1968 * Remove extents. If we get ENOSPC for a dir we have to move 1968 * Remove extents. If we get ENOSPC for a dir we have to move
1969 * the last block to the place we want to kill. 1969 * the last block to the place we want to kill.
1970 */ 1970 */
1971 if ((error = xfs_bunmapi(tp, dp, dead_blkno, count, 1971 if ((error = xfs_bunmapi(tp, dp, dead_blkno, count,
1972 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA, 1972 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA,
1973 0, args->firstblock, args->flist, 1973 0, args->firstblock, args->flist,
1974 &done)) == ENOSPC) { 1974 &done)) == ENOSPC) {
1975 if (w != XFS_DATA_FORK) 1975 if (w != XFS_DATA_FORK)
1976 goto done; 1976 goto done;
1977 if ((error = xfs_da_swap_lastblock(args, &dead_blkno, 1977 if ((error = xfs_da_swap_lastblock(args, &dead_blkno,
1978 &dead_buf))) 1978 &dead_buf)))
1979 goto done; 1979 goto done;
1980 } else if (error) 1980 } else if (error)
1981 goto done; 1981 goto done;
1982 else 1982 else
1983 break; 1983 break;
1984 } 1984 }
1985 ASSERT(done); 1985 ASSERT(done);
1986 xfs_da_binval(tp, dead_buf); 1986 xfs_da_binval(tp, dead_buf);
1987 /* 1987 /*
1988 * Adjust the directory size for version 1. 1988 * Adjust the directory size for version 1.
1989 */ 1989 */
1990 if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) { 1990 if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) {
1991 if ((error = xfs_bmap_last_offset(tp, dp, &bno, w))) 1991 if ((error = xfs_bmap_last_offset(tp, dp, &bno, w)))
1992 return error; 1992 return error;
1993 size = XFS_FSB_TO_B(dp->i_mount, bno); 1993 size = XFS_FSB_TO_B(dp->i_mount, bno);
1994 if (size != dp->i_d.di_size) { 1994 if (size != dp->i_d.di_size) {
1995 dp->i_d.di_size = size; 1995 dp->i_d.di_size = size;
1996 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); 1996 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
1997 } 1997 }
1998 } 1998 }
1999 return 0; 1999 return 0;
2000 done: 2000 done:
2001 xfs_da_binval(tp, dead_buf); 2001 xfs_da_binval(tp, dead_buf);
2002 return error; 2002 return error;
2003 } 2003 }
2004 2004
2005 /* 2005 /*
2006 * See if the mapping(s) for this btree block are valid, i.e. 2006 * See if the mapping(s) for this btree block are valid, i.e.
2007 * don't contain holes, are logically contiguous, and cover the whole range. 2007 * don't contain holes, are logically contiguous, and cover the whole range.
2008 */ 2008 */
2009 STATIC int 2009 STATIC int
2010 xfs_da_map_covers_blocks( 2010 xfs_da_map_covers_blocks(
2011 int nmap, 2011 int nmap,
2012 xfs_bmbt_irec_t *mapp, 2012 xfs_bmbt_irec_t *mapp,
2013 xfs_dablk_t bno, 2013 xfs_dablk_t bno,
2014 int count) 2014 int count)
2015 { 2015 {
2016 int i; 2016 int i;
2017 xfs_fileoff_t off; 2017 xfs_fileoff_t off;
2018 2018
2019 for (i = 0, off = bno; i < nmap; i++) { 2019 for (i = 0, off = bno; i < nmap; i++) {
2020 if (mapp[i].br_startblock == HOLESTARTBLOCK || 2020 if (mapp[i].br_startblock == HOLESTARTBLOCK ||
2021 mapp[i].br_startblock == DELAYSTARTBLOCK) { 2021 mapp[i].br_startblock == DELAYSTARTBLOCK) {
2022 return 0; 2022 return 0;
2023 } 2023 }
2024 if (off != mapp[i].br_startoff) { 2024 if (off != mapp[i].br_startoff) {
2025 return 0; 2025 return 0;
2026 } 2026 }
2027 off += mapp[i].br_blockcount; 2027 off += mapp[i].br_blockcount;
2028 } 2028 }
2029 return off == bno + count; 2029 return off == bno + count;
2030 } 2030 }
2031 2031
2032 /* 2032 /*
2033 * Make a dabuf. 2033 * Make a dabuf.
2034 * Used for get_buf, read_buf, read_bufr, and reada_buf. 2034 * Used for get_buf, read_buf, read_bufr, and reada_buf.
2035 */ 2035 */
2036 STATIC int 2036 STATIC int
2037 xfs_da_do_buf( 2037 xfs_da_do_buf(
2038 xfs_trans_t *trans, 2038 xfs_trans_t *trans,
2039 xfs_inode_t *dp, 2039 xfs_inode_t *dp,
2040 xfs_dablk_t bno, 2040 xfs_dablk_t bno,
2041 xfs_daddr_t *mappedbnop, 2041 xfs_daddr_t *mappedbnop,
2042 xfs_dabuf_t **bpp, 2042 xfs_dabuf_t **bpp,
2043 int whichfork, 2043 int whichfork,
2044 int caller, 2044 int caller,
2045 inst_t *ra) 2045 inst_t *ra)
2046 { 2046 {
2047 xfs_buf_t *bp = NULL; 2047 xfs_buf_t *bp = NULL;
2048 xfs_buf_t **bplist; 2048 xfs_buf_t **bplist;
2049 int error=0; 2049 int error=0;
2050 int i; 2050 int i;
2051 xfs_bmbt_irec_t map; 2051 xfs_bmbt_irec_t map;
2052 xfs_bmbt_irec_t *mapp; 2052 xfs_bmbt_irec_t *mapp;
2053 xfs_daddr_t mappedbno; 2053 xfs_daddr_t mappedbno;
2054 xfs_mount_t *mp; 2054 xfs_mount_t *mp;
2055 int nbplist=0; 2055 int nbplist=0;
2056 int nfsb; 2056 int nfsb;
2057 int nmap; 2057 int nmap;
2058 xfs_dabuf_t *rbp; 2058 xfs_dabuf_t *rbp;
2059 2059
2060 mp = dp->i_mount; 2060 mp = dp->i_mount;
2061 if (whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) 2061 if (whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
2062 nfsb = mp->m_dirblkfsbs; 2062 nfsb = mp->m_dirblkfsbs;
2063 else 2063 else
2064 nfsb = 1; 2064 nfsb = 1;
2065 mappedbno = *mappedbnop; 2065 mappedbno = *mappedbnop;
2066 /* 2066 /*
2067 * Caller doesn't have a mapping. -2 means don't complain 2067 * Caller doesn't have a mapping. -2 means don't complain
2068 * if we land in a hole. 2068 * if we land in a hole.
2069 */ 2069 */
2070 if (mappedbno == -1 || mappedbno == -2) { 2070 if (mappedbno == -1 || mappedbno == -2) {
2071 /* 2071 /*
2072 * Optimize the one-block case. 2072 * Optimize the one-block case.
2073 */ 2073 */
2074 if (nfsb == 1) { 2074 if (nfsb == 1) {
2075 xfs_fsblock_t fsb; 2075 xfs_fsblock_t fsb;
2076 2076
2077 if ((error = 2077 if ((error =
2078 xfs_bmapi_single(trans, dp, whichfork, &fsb, 2078 xfs_bmapi_single(trans, dp, whichfork, &fsb,
2079 (xfs_fileoff_t)bno))) { 2079 (xfs_fileoff_t)bno))) {
2080 return error; 2080 return error;
2081 } 2081 }
2082 mapp = &map; 2082 mapp = &map;
2083 if (fsb == NULLFSBLOCK) { 2083 if (fsb == NULLFSBLOCK) {
2084 nmap = 0; 2084 nmap = 0;
2085 } else { 2085 } else {
2086 map.br_startblock = fsb; 2086 map.br_startblock = fsb;
2087 map.br_startoff = (xfs_fileoff_t)bno; 2087 map.br_startoff = (xfs_fileoff_t)bno;
2088 map.br_blockcount = 1; 2088 map.br_blockcount = 1;
2089 nmap = 1; 2089 nmap = 1;
2090 } 2090 }
2091 } else { 2091 } else {
2092 mapp = kmem_alloc(sizeof(*mapp) * nfsb, KM_SLEEP); 2092 mapp = kmem_alloc(sizeof(*mapp) * nfsb, KM_SLEEP);
2093 nmap = nfsb; 2093 nmap = nfsb;
2094 if ((error = xfs_bmapi(trans, dp, (xfs_fileoff_t)bno, 2094 if ((error = xfs_bmapi(trans, dp, (xfs_fileoff_t)bno,
2095 nfsb, 2095 nfsb,
2096 XFS_BMAPI_METADATA | 2096 XFS_BMAPI_METADATA |
2097 XFS_BMAPI_AFLAG(whichfork), 2097 XFS_BMAPI_AFLAG(whichfork),
2098 NULL, 0, mapp, &nmap, NULL))) 2098 NULL, 0, mapp, &nmap, NULL)))
2099 goto exit0; 2099 goto exit0;
2100 } 2100 }
2101 } else { 2101 } else {
2102 map.br_startblock = XFS_DADDR_TO_FSB(mp, mappedbno); 2102 map.br_startblock = XFS_DADDR_TO_FSB(mp, mappedbno);
2103 map.br_startoff = (xfs_fileoff_t)bno; 2103 map.br_startoff = (xfs_fileoff_t)bno;
2104 map.br_blockcount = nfsb; 2104 map.br_blockcount = nfsb;
2105 mapp = &map; 2105 mapp = &map;
2106 nmap = 1; 2106 nmap = 1;
2107 } 2107 }
2108 if (!xfs_da_map_covers_blocks(nmap, mapp, bno, nfsb)) { 2108 if (!xfs_da_map_covers_blocks(nmap, mapp, bno, nfsb)) {
2109 error = mappedbno == -2 ? 0 : XFS_ERROR(EFSCORRUPTED); 2109 error = mappedbno == -2 ? 0 : XFS_ERROR(EFSCORRUPTED);
2110 if (unlikely(error == EFSCORRUPTED)) { 2110 if (unlikely(error == EFSCORRUPTED)) {
2111 if (xfs_error_level >= XFS_ERRLEVEL_LOW) { 2111 if (xfs_error_level >= XFS_ERRLEVEL_LOW) {
2112 int i; 2112 int i;
2113 cmn_err(CE_ALERT, "xfs_da_do_buf: bno %lld\n", 2113 cmn_err(CE_ALERT, "xfs_da_do_buf: bno %lld\n",
2114 (long long)bno); 2114 (long long)bno);
2115 cmn_err(CE_ALERT, "dir: inode %lld\n", 2115 cmn_err(CE_ALERT, "dir: inode %lld\n",
2116 (long long)dp->i_ino); 2116 (long long)dp->i_ino);
2117 for (i = 0; i < nmap; i++) { 2117 for (i = 0; i < nmap; i++) {
2118 cmn_err(CE_ALERT, 2118 cmn_err(CE_ALERT,
2119 "[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d\n", 2119 "[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d\n",
2120 i, 2120 i,
2121 (long long)mapp[i].br_startoff, 2121 (long long)mapp[i].br_startoff,
2122 (long long)mapp[i].br_startblock, 2122 (long long)mapp[i].br_startblock,
2123 (long long)mapp[i].br_blockcount, 2123 (long long)mapp[i].br_blockcount,
2124 mapp[i].br_state); 2124 mapp[i].br_state);
2125 } 2125 }
2126 } 2126 }
2127 XFS_ERROR_REPORT("xfs_da_do_buf(1)", 2127 XFS_ERROR_REPORT("xfs_da_do_buf(1)",
2128 XFS_ERRLEVEL_LOW, mp); 2128 XFS_ERRLEVEL_LOW, mp);
2129 } 2129 }
2130 goto exit0; 2130 goto exit0;
2131 } 2131 }
2132 if (caller != 3 && nmap > 1) { 2132 if (caller != 3 && nmap > 1) {
2133 bplist = kmem_alloc(sizeof(*bplist) * nmap, KM_SLEEP); 2133 bplist = kmem_alloc(sizeof(*bplist) * nmap, KM_SLEEP);
2134 nbplist = 0; 2134 nbplist = 0;
2135 } else 2135 } else
2136 bplist = NULL; 2136 bplist = NULL;
2137 /* 2137 /*
2138 * Turn the mapping(s) into buffer(s). 2138 * Turn the mapping(s) into buffer(s).
2139 */ 2139 */
2140 for (i = 0; i < nmap; i++) { 2140 for (i = 0; i < nmap; i++) {
2141 int nmapped; 2141 int nmapped;
2142 2142
2143 mappedbno = XFS_FSB_TO_DADDR(mp, mapp[i].br_startblock); 2143 mappedbno = XFS_FSB_TO_DADDR(mp, mapp[i].br_startblock);
2144 if (i == 0) 2144 if (i == 0)
2145 *mappedbnop = mappedbno; 2145 *mappedbnop = mappedbno;
2146 nmapped = (int)XFS_FSB_TO_BB(mp, mapp[i].br_blockcount); 2146 nmapped = (int)XFS_FSB_TO_BB(mp, mapp[i].br_blockcount);
2147 switch (caller) { 2147 switch (caller) {
2148 case 0: 2148 case 0:
2149 bp = xfs_trans_get_buf(trans, mp->m_ddev_targp, 2149 bp = xfs_trans_get_buf(trans, mp->m_ddev_targp,
2150 mappedbno, nmapped, 0); 2150 mappedbno, nmapped, 0);
2151 error = bp ? XFS_BUF_GETERROR(bp) : XFS_ERROR(EIO); 2151 error = bp ? XFS_BUF_GETERROR(bp) : XFS_ERROR(EIO);
2152 break; 2152 break;
2153 case 1: 2153 case 1:
2154 case 2: 2154 case 2:
2155 bp = NULL; 2155 bp = NULL;
2156 error = xfs_trans_read_buf(mp, trans, mp->m_ddev_targp, 2156 error = xfs_trans_read_buf(mp, trans, mp->m_ddev_targp,
2157 mappedbno, nmapped, 0, &bp); 2157 mappedbno, nmapped, 0, &bp);
2158 break; 2158 break;
2159 case 3: 2159 case 3:
2160 xfs_baread(mp->m_ddev_targp, mappedbno, nmapped); 2160 xfs_baread(mp->m_ddev_targp, mappedbno, nmapped);
2161 error = 0; 2161 error = 0;
2162 bp = NULL; 2162 bp = NULL;
2163 break; 2163 break;
2164 } 2164 }
2165 if (error) { 2165 if (error) {
2166 if (bp) 2166 if (bp)
2167 xfs_trans_brelse(trans, bp); 2167 xfs_trans_brelse(trans, bp);
2168 goto exit1; 2168 goto exit1;
2169 } 2169 }
2170 if (!bp) 2170 if (!bp)
2171 continue; 2171 continue;
2172 if (caller == 1) { 2172 if (caller == 1) {
2173 if (whichfork == XFS_ATTR_FORK) { 2173 if (whichfork == XFS_ATTR_FORK) {
2174 XFS_BUF_SET_VTYPE_REF(bp, B_FS_ATTR_BTREE, 2174 XFS_BUF_SET_VTYPE_REF(bp, B_FS_ATTR_BTREE,
2175 XFS_ATTR_BTREE_REF); 2175 XFS_ATTR_BTREE_REF);
2176 } else { 2176 } else {
2177 XFS_BUF_SET_VTYPE_REF(bp, B_FS_DIR_BTREE, 2177 XFS_BUF_SET_VTYPE_REF(bp, B_FS_DIR_BTREE,
2178 XFS_DIR_BTREE_REF); 2178 XFS_DIR_BTREE_REF);
2179 } 2179 }
2180 } 2180 }
2181 if (bplist) { 2181 if (bplist) {
2182 bplist[nbplist++] = bp; 2182 bplist[nbplist++] = bp;
2183 } 2183 }
2184 } 2184 }
2185 /* 2185 /*
2186 * Build a dabuf structure. 2186 * Build a dabuf structure.
2187 */ 2187 */
2188 if (bplist) { 2188 if (bplist) {
2189 rbp = xfs_da_buf_make(nbplist, bplist, ra); 2189 rbp = xfs_da_buf_make(nbplist, bplist, ra);
2190 } else if (bp) 2190 } else if (bp)
2191 rbp = xfs_da_buf_make(1, &bp, ra); 2191 rbp = xfs_da_buf_make(1, &bp, ra);
2192 else 2192 else
2193 rbp = NULL; 2193 rbp = NULL;
2194 /* 2194 /*
2195 * For read_buf, check the magic number. 2195 * For read_buf, check the magic number.
2196 */ 2196 */
2197 if (caller == 1) { 2197 if (caller == 1) {
2198 xfs_dir2_data_t *data; 2198 xfs_dir2_data_t *data;
2199 xfs_dir2_free_t *free; 2199 xfs_dir2_free_t *free;
2200 xfs_da_blkinfo_t *info; 2200 xfs_da_blkinfo_t *info;
2201 uint magic, magic1; 2201 uint magic, magic1;
2202 2202
2203 info = rbp->data; 2203 info = rbp->data;
2204 data = rbp->data; 2204 data = rbp->data;
2205 free = rbp->data; 2205 free = rbp->data;
2206 magic = INT_GET(info->magic, ARCH_CONVERT); 2206 magic = INT_GET(info->magic, ARCH_CONVERT);
2207 magic1 = INT_GET(data->hdr.magic, ARCH_CONVERT); 2207 magic1 = be32_to_cpu(data->hdr.magic);
2208 if (unlikely( 2208 if (unlikely(
2209 XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && 2209 XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
2210 (magic != XFS_DIR_LEAF_MAGIC) && 2210 (magic != XFS_DIR_LEAF_MAGIC) &&
2211 (magic != XFS_ATTR_LEAF_MAGIC) && 2211 (magic != XFS_ATTR_LEAF_MAGIC) &&
2212 (magic != XFS_DIR2_LEAF1_MAGIC) && 2212 (magic != XFS_DIR2_LEAF1_MAGIC) &&
2213 (magic != XFS_DIR2_LEAFN_MAGIC) && 2213 (magic != XFS_DIR2_LEAFN_MAGIC) &&
2214 (magic1 != XFS_DIR2_BLOCK_MAGIC) && 2214 (magic1 != XFS_DIR2_BLOCK_MAGIC) &&
2215 (magic1 != XFS_DIR2_DATA_MAGIC) && 2215 (magic1 != XFS_DIR2_DATA_MAGIC) &&
2216 (INT_GET(free->hdr.magic, ARCH_CONVERT) != XFS_DIR2_FREE_MAGIC), 2216 (INT_GET(free->hdr.magic, ARCH_CONVERT) != XFS_DIR2_FREE_MAGIC),
2217 mp, XFS_ERRTAG_DA_READ_BUF, 2217 mp, XFS_ERRTAG_DA_READ_BUF,
2218 XFS_RANDOM_DA_READ_BUF))) { 2218 XFS_RANDOM_DA_READ_BUF))) {
2219 xfs_buftrace("DA READ ERROR", rbp->bps[0]); 2219 xfs_buftrace("DA READ ERROR", rbp->bps[0]);
2220 XFS_CORRUPTION_ERROR("xfs_da_do_buf(2)", 2220 XFS_CORRUPTION_ERROR("xfs_da_do_buf(2)",
2221 XFS_ERRLEVEL_LOW, mp, info); 2221 XFS_ERRLEVEL_LOW, mp, info);
2222 error = XFS_ERROR(EFSCORRUPTED); 2222 error = XFS_ERROR(EFSCORRUPTED);
2223 xfs_da_brelse(trans, rbp); 2223 xfs_da_brelse(trans, rbp);
2224 nbplist = 0; 2224 nbplist = 0;
2225 goto exit1; 2225 goto exit1;
2226 } 2226 }
2227 } 2227 }
2228 if (bplist) { 2228 if (bplist) {
2229 kmem_free(bplist, sizeof(*bplist) * nmap); 2229 kmem_free(bplist, sizeof(*bplist) * nmap);
2230 } 2230 }
2231 if (mapp != &map) { 2231 if (mapp != &map) {
2232 kmem_free(mapp, sizeof(*mapp) * nfsb); 2232 kmem_free(mapp, sizeof(*mapp) * nfsb);
2233 } 2233 }
2234 if (bpp) 2234 if (bpp)
2235 *bpp = rbp; 2235 *bpp = rbp;
2236 return 0; 2236 return 0;
2237 exit1: 2237 exit1:
2238 if (bplist) { 2238 if (bplist) {
2239 for (i = 0; i < nbplist; i++) 2239 for (i = 0; i < nbplist; i++)
2240 xfs_trans_brelse(trans, bplist[i]); 2240 xfs_trans_brelse(trans, bplist[i]);
2241 kmem_free(bplist, sizeof(*bplist) * nmap); 2241 kmem_free(bplist, sizeof(*bplist) * nmap);
2242 } 2242 }
2243 exit0: 2243 exit0:
2244 if (mapp != &map) 2244 if (mapp != &map)
2245 kmem_free(mapp, sizeof(*mapp) * nfsb); 2245 kmem_free(mapp, sizeof(*mapp) * nfsb);
2246 if (bpp) 2246 if (bpp)
2247 *bpp = NULL; 2247 *bpp = NULL;
2248 return error; 2248 return error;
2249 } 2249 }
2250 2250
2251 /* 2251 /*
2252 * Get a buffer for the dir/attr block. 2252 * Get a buffer for the dir/attr block.
2253 */ 2253 */
2254 int 2254 int
2255 xfs_da_get_buf( 2255 xfs_da_get_buf(
2256 xfs_trans_t *trans, 2256 xfs_trans_t *trans,
2257 xfs_inode_t *dp, 2257 xfs_inode_t *dp,
2258 xfs_dablk_t bno, 2258 xfs_dablk_t bno,
2259 xfs_daddr_t mappedbno, 2259 xfs_daddr_t mappedbno,
2260 xfs_dabuf_t **bpp, 2260 xfs_dabuf_t **bpp,
2261 int whichfork) 2261 int whichfork)
2262 { 2262 {
2263 return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 0, 2263 return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 0,
2264 (inst_t *)__return_address); 2264 (inst_t *)__return_address);
2265 } 2265 }
2266 2266
2267 /* 2267 /*
2268 * Get a buffer for the dir/attr block, fill in the contents. 2268 * Get a buffer for the dir/attr block, fill in the contents.
2269 */ 2269 */
2270 int 2270 int
2271 xfs_da_read_buf( 2271 xfs_da_read_buf(
2272 xfs_trans_t *trans, 2272 xfs_trans_t *trans,
2273 xfs_inode_t *dp, 2273 xfs_inode_t *dp,
2274 xfs_dablk_t bno, 2274 xfs_dablk_t bno,
2275 xfs_daddr_t mappedbno, 2275 xfs_daddr_t mappedbno,
2276 xfs_dabuf_t **bpp, 2276 xfs_dabuf_t **bpp,
2277 int whichfork) 2277 int whichfork)
2278 { 2278 {
2279 return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 1, 2279 return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 1,
2280 (inst_t *)__return_address); 2280 (inst_t *)__return_address);
2281 } 2281 }
2282 2282
2283 /* 2283 /*
2284 * Readahead the dir/attr block. 2284 * Readahead the dir/attr block.
2285 */ 2285 */
2286 xfs_daddr_t 2286 xfs_daddr_t
2287 xfs_da_reada_buf( 2287 xfs_da_reada_buf(
2288 xfs_trans_t *trans, 2288 xfs_trans_t *trans,
2289 xfs_inode_t *dp, 2289 xfs_inode_t *dp,
2290 xfs_dablk_t bno, 2290 xfs_dablk_t bno,
2291 int whichfork) 2291 int whichfork)
2292 { 2292 {
2293 xfs_daddr_t rval; 2293 xfs_daddr_t rval;
2294 2294
2295 rval = -1; 2295 rval = -1;
2296 if (xfs_da_do_buf(trans, dp, bno, &rval, NULL, whichfork, 3, 2296 if (xfs_da_do_buf(trans, dp, bno, &rval, NULL, whichfork, 3,
2297 (inst_t *)__return_address)) 2297 (inst_t *)__return_address))
2298 return -1; 2298 return -1;
2299 else 2299 else
2300 return rval; 2300 return rval;
2301 } 2301 }
2302 2302
2303 /* 2303 /*
2304 * Calculate the number of bits needed to hold i different values. 2304 * Calculate the number of bits needed to hold i different values.
2305 */ 2305 */
2306 uint 2306 uint
2307 xfs_da_log2_roundup(uint i) 2307 xfs_da_log2_roundup(uint i)
2308 { 2308 {
2309 uint rval; 2309 uint rval;
2310 2310
2311 for (rval = 0; rval < NBBY * sizeof(i); rval++) { 2311 for (rval = 0; rval < NBBY * sizeof(i); rval++) {
2312 if ((1 << rval) >= i) 2312 if ((1 << rval) >= i)
2313 break; 2313 break;
2314 } 2314 }
2315 return(rval); 2315 return(rval);
2316 } 2316 }
2317 2317
2318 kmem_zone_t *xfs_da_state_zone; /* anchor for state struct zone */ 2318 kmem_zone_t *xfs_da_state_zone; /* anchor for state struct zone */
2319 kmem_zone_t *xfs_dabuf_zone; /* dabuf zone */ 2319 kmem_zone_t *xfs_dabuf_zone; /* dabuf zone */
2320 2320
2321 /* 2321 /*
2322 * Allocate a dir-state structure. 2322 * Allocate a dir-state structure.
2323 * We don't put them on the stack since they're large. 2323 * We don't put them on the stack since they're large.
2324 */ 2324 */
2325 xfs_da_state_t * 2325 xfs_da_state_t *
2326 xfs_da_state_alloc(void) 2326 xfs_da_state_alloc(void)
2327 { 2327 {
2328 return kmem_zone_zalloc(xfs_da_state_zone, KM_SLEEP); 2328 return kmem_zone_zalloc(xfs_da_state_zone, KM_SLEEP);
2329 } 2329 }
2330 2330
2331 /* 2331 /*
2332 * Kill the altpath contents of a da-state structure. 2332 * Kill the altpath contents of a da-state structure.
2333 */ 2333 */
2334 STATIC void 2334 STATIC void
2335 xfs_da_state_kill_altpath(xfs_da_state_t *state) 2335 xfs_da_state_kill_altpath(xfs_da_state_t *state)
2336 { 2336 {
2337 int i; 2337 int i;
2338 2338
2339 for (i = 0; i < state->altpath.active; i++) { 2339 for (i = 0; i < state->altpath.active; i++) {
2340 if (state->altpath.blk[i].bp) { 2340 if (state->altpath.blk[i].bp) {
2341 if (state->altpath.blk[i].bp != state->path.blk[i].bp) 2341 if (state->altpath.blk[i].bp != state->path.blk[i].bp)
2342 xfs_da_buf_done(state->altpath.blk[i].bp); 2342 xfs_da_buf_done(state->altpath.blk[i].bp);
2343 state->altpath.blk[i].bp = NULL; 2343 state->altpath.blk[i].bp = NULL;
2344 } 2344 }
2345 } 2345 }
2346 state->altpath.active = 0; 2346 state->altpath.active = 0;
2347 } 2347 }
2348 2348
2349 /* 2349 /*
2350 * Free a da-state structure. 2350 * Free a da-state structure.
2351 */ 2351 */
2352 void 2352 void
2353 xfs_da_state_free(xfs_da_state_t *state) 2353 xfs_da_state_free(xfs_da_state_t *state)
2354 { 2354 {
2355 int i; 2355 int i;
2356 2356
2357 xfs_da_state_kill_altpath(state); 2357 xfs_da_state_kill_altpath(state);
2358 for (i = 0; i < state->path.active; i++) { 2358 for (i = 0; i < state->path.active; i++) {
2359 if (state->path.blk[i].bp) 2359 if (state->path.blk[i].bp)
2360 xfs_da_buf_done(state->path.blk[i].bp); 2360 xfs_da_buf_done(state->path.blk[i].bp);
2361 } 2361 }
2362 if (state->extravalid && state->extrablk.bp) 2362 if (state->extravalid && state->extrablk.bp)
2363 xfs_da_buf_done(state->extrablk.bp); 2363 xfs_da_buf_done(state->extrablk.bp);
2364 #ifdef DEBUG 2364 #ifdef DEBUG
2365 memset((char *)state, 0, sizeof(*state)); 2365 memset((char *)state, 0, sizeof(*state));
2366 #endif /* DEBUG */ 2366 #endif /* DEBUG */
2367 kmem_zone_free(xfs_da_state_zone, state); 2367 kmem_zone_free(xfs_da_state_zone, state);
2368 } 2368 }
2369 2369
2370 #ifdef XFS_DABUF_DEBUG 2370 #ifdef XFS_DABUF_DEBUG
2371 xfs_dabuf_t *xfs_dabuf_global_list; 2371 xfs_dabuf_t *xfs_dabuf_global_list;
2372 lock_t xfs_dabuf_global_lock; 2372 lock_t xfs_dabuf_global_lock;
2373 #endif 2373 #endif
2374 2374
2375 /* 2375 /*
2376 * Create a dabuf. 2376 * Create a dabuf.
2377 */ 2377 */
2378 /* ARGSUSED */ 2378 /* ARGSUSED */
2379 STATIC xfs_dabuf_t * 2379 STATIC xfs_dabuf_t *
2380 xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra) 2380 xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra)
2381 { 2381 {
2382 xfs_buf_t *bp; 2382 xfs_buf_t *bp;
2383 xfs_dabuf_t *dabuf; 2383 xfs_dabuf_t *dabuf;
2384 int i; 2384 int i;
2385 int off; 2385 int off;
2386 2386
2387 if (nbuf == 1) 2387 if (nbuf == 1)
2388 dabuf = kmem_zone_alloc(xfs_dabuf_zone, KM_SLEEP); 2388 dabuf = kmem_zone_alloc(xfs_dabuf_zone, KM_SLEEP);
2389 else 2389 else
2390 dabuf = kmem_alloc(XFS_DA_BUF_SIZE(nbuf), KM_SLEEP); 2390 dabuf = kmem_alloc(XFS_DA_BUF_SIZE(nbuf), KM_SLEEP);
2391 dabuf->dirty = 0; 2391 dabuf->dirty = 0;
2392 #ifdef XFS_DABUF_DEBUG 2392 #ifdef XFS_DABUF_DEBUG
2393 dabuf->ra = ra; 2393 dabuf->ra = ra;
2394 dabuf->target = XFS_BUF_TARGET(bps[0]); 2394 dabuf->target = XFS_BUF_TARGET(bps[0]);
2395 dabuf->blkno = XFS_BUF_ADDR(bps[0]); 2395 dabuf->blkno = XFS_BUF_ADDR(bps[0]);
2396 #endif 2396 #endif
2397 if (nbuf == 1) { 2397 if (nbuf == 1) {
2398 dabuf->nbuf = 1; 2398 dabuf->nbuf = 1;
2399 bp = bps[0]; 2399 bp = bps[0];
2400 dabuf->bbcount = (short)BTOBB(XFS_BUF_COUNT(bp)); 2400 dabuf->bbcount = (short)BTOBB(XFS_BUF_COUNT(bp));
2401 dabuf->data = XFS_BUF_PTR(bp); 2401 dabuf->data = XFS_BUF_PTR(bp);
2402 dabuf->bps[0] = bp; 2402 dabuf->bps[0] = bp;
2403 } else { 2403 } else {
2404 dabuf->nbuf = nbuf; 2404 dabuf->nbuf = nbuf;
2405 for (i = 0, dabuf->bbcount = 0; i < nbuf; i++) { 2405 for (i = 0, dabuf->bbcount = 0; i < nbuf; i++) {
2406 dabuf->bps[i] = bp = bps[i]; 2406 dabuf->bps[i] = bp = bps[i];
2407 dabuf->bbcount += BTOBB(XFS_BUF_COUNT(bp)); 2407 dabuf->bbcount += BTOBB(XFS_BUF_COUNT(bp));
2408 } 2408 }
2409 dabuf->data = kmem_alloc(BBTOB(dabuf->bbcount), KM_SLEEP); 2409 dabuf->data = kmem_alloc(BBTOB(dabuf->bbcount), KM_SLEEP);
2410 for (i = off = 0; i < nbuf; i++, off += XFS_BUF_COUNT(bp)) { 2410 for (i = off = 0; i < nbuf; i++, off += XFS_BUF_COUNT(bp)) {
2411 bp = bps[i]; 2411 bp = bps[i];
2412 memcpy((char *)dabuf->data + off, XFS_BUF_PTR(bp), 2412 memcpy((char *)dabuf->data + off, XFS_BUF_PTR(bp),
2413 XFS_BUF_COUNT(bp)); 2413 XFS_BUF_COUNT(bp));
2414 } 2414 }
2415 } 2415 }
2416 #ifdef XFS_DABUF_DEBUG 2416 #ifdef XFS_DABUF_DEBUG
2417 { 2417 {
2418 SPLDECL(s); 2418 SPLDECL(s);
2419 xfs_dabuf_t *p; 2419 xfs_dabuf_t *p;
2420 2420
2421 s = mutex_spinlock(&xfs_dabuf_global_lock); 2421 s = mutex_spinlock(&xfs_dabuf_global_lock);
2422 for (p = xfs_dabuf_global_list; p; p = p->next) { 2422 for (p = xfs_dabuf_global_list; p; p = p->next) {
2423 ASSERT(p->blkno != dabuf->blkno || 2423 ASSERT(p->blkno != dabuf->blkno ||
2424 p->target != dabuf->target); 2424 p->target != dabuf->target);
2425 } 2425 }
2426 dabuf->prev = NULL; 2426 dabuf->prev = NULL;
2427 if (xfs_dabuf_global_list) 2427 if (xfs_dabuf_global_list)
2428 xfs_dabuf_global_list->prev = dabuf; 2428 xfs_dabuf_global_list->prev = dabuf;
2429 dabuf->next = xfs_dabuf_global_list; 2429 dabuf->next = xfs_dabuf_global_list;
2430 xfs_dabuf_global_list = dabuf; 2430 xfs_dabuf_global_list = dabuf;
2431 mutex_spinunlock(&xfs_dabuf_global_lock, s); 2431 mutex_spinunlock(&xfs_dabuf_global_lock, s);
2432 } 2432 }
2433 #endif 2433 #endif
2434 return dabuf; 2434 return dabuf;
2435 } 2435 }
2436 2436
2437 /* 2437 /*
2438 * Un-dirty a dabuf. 2438 * Un-dirty a dabuf.
2439 */ 2439 */
2440 STATIC void 2440 STATIC void
2441 xfs_da_buf_clean(xfs_dabuf_t *dabuf) 2441 xfs_da_buf_clean(xfs_dabuf_t *dabuf)
2442 { 2442 {
2443 xfs_buf_t *bp; 2443 xfs_buf_t *bp;
2444 int i; 2444 int i;
2445 int off; 2445 int off;
2446 2446
2447 if (dabuf->dirty) { 2447 if (dabuf->dirty) {
2448 ASSERT(dabuf->nbuf > 1); 2448 ASSERT(dabuf->nbuf > 1);
2449 dabuf->dirty = 0; 2449 dabuf->dirty = 0;
2450 for (i = off = 0; i < dabuf->nbuf; 2450 for (i = off = 0; i < dabuf->nbuf;
2451 i++, off += XFS_BUF_COUNT(bp)) { 2451 i++, off += XFS_BUF_COUNT(bp)) {
2452 bp = dabuf->bps[i]; 2452 bp = dabuf->bps[i];
2453 memcpy(XFS_BUF_PTR(bp), (char *)dabuf->data + off, 2453 memcpy(XFS_BUF_PTR(bp), (char *)dabuf->data + off,
2454 XFS_BUF_COUNT(bp)); 2454 XFS_BUF_COUNT(bp));
2455 } 2455 }
2456 } 2456 }
2457 } 2457 }
2458 2458
2459 /* 2459 /*
2460 * Release a dabuf. 2460 * Release a dabuf.
2461 */ 2461 */
2462 void 2462 void
2463 xfs_da_buf_done(xfs_dabuf_t *dabuf) 2463 xfs_da_buf_done(xfs_dabuf_t *dabuf)
2464 { 2464 {
2465 ASSERT(dabuf); 2465 ASSERT(dabuf);
2466 ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); 2466 ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]);
2467 if (dabuf->dirty) 2467 if (dabuf->dirty)
2468 xfs_da_buf_clean(dabuf); 2468 xfs_da_buf_clean(dabuf);
2469 if (dabuf->nbuf > 1) 2469 if (dabuf->nbuf > 1)
2470 kmem_free(dabuf->data, BBTOB(dabuf->bbcount)); 2470 kmem_free(dabuf->data, BBTOB(dabuf->bbcount));
2471 #ifdef XFS_DABUF_DEBUG 2471 #ifdef XFS_DABUF_DEBUG
2472 { 2472 {
2473 SPLDECL(s); 2473 SPLDECL(s);
2474 2474
2475 s = mutex_spinlock(&xfs_dabuf_global_lock); 2475 s = mutex_spinlock(&xfs_dabuf_global_lock);
2476 if (dabuf->prev) 2476 if (dabuf->prev)
2477 dabuf->prev->next = dabuf->next; 2477 dabuf->prev->next = dabuf->next;
2478 else 2478 else
2479 xfs_dabuf_global_list = dabuf->next; 2479 xfs_dabuf_global_list = dabuf->next;
2480 if (dabuf->next) 2480 if (dabuf->next)
2481 dabuf->next->prev = dabuf->prev; 2481 dabuf->next->prev = dabuf->prev;
2482 mutex_spinunlock(&xfs_dabuf_global_lock, s); 2482 mutex_spinunlock(&xfs_dabuf_global_lock, s);
2483 } 2483 }
2484 memset(dabuf, 0, XFS_DA_BUF_SIZE(dabuf->nbuf)); 2484 memset(dabuf, 0, XFS_DA_BUF_SIZE(dabuf->nbuf));
2485 #endif 2485 #endif
2486 if (dabuf->nbuf == 1) 2486 if (dabuf->nbuf == 1)
2487 kmem_zone_free(xfs_dabuf_zone, dabuf); 2487 kmem_zone_free(xfs_dabuf_zone, dabuf);
2488 else 2488 else
2489 kmem_free(dabuf, XFS_DA_BUF_SIZE(dabuf->nbuf)); 2489 kmem_free(dabuf, XFS_DA_BUF_SIZE(dabuf->nbuf));
2490 } 2490 }
2491 2491
2492 /* 2492 /*
2493 * Log transaction from a dabuf. 2493 * Log transaction from a dabuf.
2494 */ 2494 */
2495 void 2495 void
2496 xfs_da_log_buf(xfs_trans_t *tp, xfs_dabuf_t *dabuf, uint first, uint last) 2496 xfs_da_log_buf(xfs_trans_t *tp, xfs_dabuf_t *dabuf, uint first, uint last)
2497 { 2497 {
2498 xfs_buf_t *bp; 2498 xfs_buf_t *bp;
2499 uint f; 2499 uint f;
2500 int i; 2500 int i;
2501 uint l; 2501 uint l;
2502 int off; 2502 int off;
2503 2503
2504 ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); 2504 ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]);
2505 if (dabuf->nbuf == 1) { 2505 if (dabuf->nbuf == 1) {
2506 ASSERT(dabuf->data == (void *)XFS_BUF_PTR(dabuf->bps[0])); 2506 ASSERT(dabuf->data == (void *)XFS_BUF_PTR(dabuf->bps[0]));
2507 xfs_trans_log_buf(tp, dabuf->bps[0], first, last); 2507 xfs_trans_log_buf(tp, dabuf->bps[0], first, last);
2508 return; 2508 return;
2509 } 2509 }
2510 dabuf->dirty = 1; 2510 dabuf->dirty = 1;
2511 ASSERT(first <= last); 2511 ASSERT(first <= last);
2512 for (i = off = 0; i < dabuf->nbuf; i++, off += XFS_BUF_COUNT(bp)) { 2512 for (i = off = 0; i < dabuf->nbuf; i++, off += XFS_BUF_COUNT(bp)) {
2513 bp = dabuf->bps[i]; 2513 bp = dabuf->bps[i];
2514 f = off; 2514 f = off;
2515 l = f + XFS_BUF_COUNT(bp) - 1; 2515 l = f + XFS_BUF_COUNT(bp) - 1;
2516 if (f < first) 2516 if (f < first)
2517 f = first; 2517 f = first;
2518 if (l > last) 2518 if (l > last)
2519 l = last; 2519 l = last;
2520 if (f <= l) 2520 if (f <= l)
2521 xfs_trans_log_buf(tp, bp, f - off, l - off); 2521 xfs_trans_log_buf(tp, bp, f - off, l - off);
2522 /* 2522 /*
2523 * B_DONE is set by xfs_trans_log buf. 2523 * B_DONE is set by xfs_trans_log buf.
2524 * If we don't set it on a new buffer (get not read) 2524 * If we don't set it on a new buffer (get not read)
2525 * then if we don't put anything in the buffer it won't 2525 * then if we don't put anything in the buffer it won't
2526 * be set, and at commit it it released into the cache, 2526 * be set, and at commit it it released into the cache,
2527 * and then a read will fail. 2527 * and then a read will fail.
2528 */ 2528 */
2529 else if (!(XFS_BUF_ISDONE(bp))) 2529 else if (!(XFS_BUF_ISDONE(bp)))
2530 XFS_BUF_DONE(bp); 2530 XFS_BUF_DONE(bp);
2531 } 2531 }
2532 ASSERT(last < off); 2532 ASSERT(last < off);
2533 } 2533 }
2534 2534
2535 /* 2535 /*
2536 * Release dabuf from a transaction. 2536 * Release dabuf from a transaction.
2537 * Have to free up the dabuf before the buffers are released, 2537 * Have to free up the dabuf before the buffers are released,
2538 * since the synchronization on the dabuf is really the lock on the buffer. 2538 * since the synchronization on the dabuf is really the lock on the buffer.
2539 */ 2539 */
2540 void 2540 void
2541 xfs_da_brelse(xfs_trans_t *tp, xfs_dabuf_t *dabuf) 2541 xfs_da_brelse(xfs_trans_t *tp, xfs_dabuf_t *dabuf)
2542 { 2542 {
2543 xfs_buf_t *bp; 2543 xfs_buf_t *bp;
2544 xfs_buf_t **bplist; 2544 xfs_buf_t **bplist;
2545 int i; 2545 int i;
2546 int nbuf; 2546 int nbuf;
2547 2547
2548 ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); 2548 ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]);
2549 if ((nbuf = dabuf->nbuf) == 1) { 2549 if ((nbuf = dabuf->nbuf) == 1) {
2550 bplist = &bp; 2550 bplist = &bp;
2551 bp = dabuf->bps[0]; 2551 bp = dabuf->bps[0];
2552 } else { 2552 } else {
2553 bplist = kmem_alloc(nbuf * sizeof(*bplist), KM_SLEEP); 2553 bplist = kmem_alloc(nbuf * sizeof(*bplist), KM_SLEEP);
2554 memcpy(bplist, dabuf->bps, nbuf * sizeof(*bplist)); 2554 memcpy(bplist, dabuf->bps, nbuf * sizeof(*bplist));
2555 } 2555 }
2556 xfs_da_buf_done(dabuf); 2556 xfs_da_buf_done(dabuf);
2557 for (i = 0; i < nbuf; i++) 2557 for (i = 0; i < nbuf; i++)
2558 xfs_trans_brelse(tp, bplist[i]); 2558 xfs_trans_brelse(tp, bplist[i]);
2559 if (bplist != &bp) 2559 if (bplist != &bp)
2560 kmem_free(bplist, nbuf * sizeof(*bplist)); 2560 kmem_free(bplist, nbuf * sizeof(*bplist));
2561 } 2561 }
2562 2562
2563 /* 2563 /*
2564 * Invalidate dabuf from a transaction. 2564 * Invalidate dabuf from a transaction.
2565 */ 2565 */
2566 void 2566 void
2567 xfs_da_binval(xfs_trans_t *tp, xfs_dabuf_t *dabuf) 2567 xfs_da_binval(xfs_trans_t *tp, xfs_dabuf_t *dabuf)
2568 { 2568 {
2569 xfs_buf_t *bp; 2569 xfs_buf_t *bp;
2570 xfs_buf_t **bplist; 2570 xfs_buf_t **bplist;
2571 int i; 2571 int i;
2572 int nbuf; 2572 int nbuf;
2573 2573
2574 ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); 2574 ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]);
2575 if ((nbuf = dabuf->nbuf) == 1) { 2575 if ((nbuf = dabuf->nbuf) == 1) {
2576 bplist = &bp; 2576 bplist = &bp;
2577 bp = dabuf->bps[0]; 2577 bp = dabuf->bps[0];
2578 } else { 2578 } else {
2579 bplist = kmem_alloc(nbuf * sizeof(*bplist), KM_SLEEP); 2579 bplist = kmem_alloc(nbuf * sizeof(*bplist), KM_SLEEP);
2580 memcpy(bplist, dabuf->bps, nbuf * sizeof(*bplist)); 2580 memcpy(bplist, dabuf->bps, nbuf * sizeof(*bplist));
2581 } 2581 }
2582 xfs_da_buf_done(dabuf); 2582 xfs_da_buf_done(dabuf);
2583 for (i = 0; i < nbuf; i++) 2583 for (i = 0; i < nbuf; i++)
2584 xfs_trans_binval(tp, bplist[i]); 2584 xfs_trans_binval(tp, bplist[i]);
2585 if (bplist != &bp) 2585 if (bplist != &bp)
2586 kmem_free(bplist, nbuf * sizeof(*bplist)); 2586 kmem_free(bplist, nbuf * sizeof(*bplist));
2587 } 2587 }
2588 2588
2589 /* 2589 /*
2590 * Get the first daddr from a dabuf. 2590 * Get the first daddr from a dabuf.
2591 */ 2591 */
2592 xfs_daddr_t 2592 xfs_daddr_t
2593 xfs_da_blkno(xfs_dabuf_t *dabuf) 2593 xfs_da_blkno(xfs_dabuf_t *dabuf)
2594 { 2594 {
2595 ASSERT(dabuf->nbuf); 2595 ASSERT(dabuf->nbuf);
2596 ASSERT(dabuf->data); 2596 ASSERT(dabuf->data);
2597 return XFS_BUF_ADDR(dabuf->bps[0]); 2597 return XFS_BUF_ADDR(dabuf->bps[0]);
2598 } 2598 }
2599 2599
fs/xfs/xfs_dir2_block.c
1 /* 1 /*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 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 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 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, 15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18 #include "xfs.h" 18 #include "xfs.h"
19 #include "xfs_fs.h" 19 #include "xfs_fs.h"
20 #include "xfs_types.h" 20 #include "xfs_types.h"
21 #include "xfs_log.h" 21 #include "xfs_log.h"
22 #include "xfs_inum.h" 22 #include "xfs_inum.h"
23 #include "xfs_trans.h" 23 #include "xfs_trans.h"
24 #include "xfs_sb.h" 24 #include "xfs_sb.h"
25 #include "xfs_dir.h" 25 #include "xfs_dir.h"
26 #include "xfs_dir2.h" 26 #include "xfs_dir2.h"
27 #include "xfs_dmapi.h" 27 #include "xfs_dmapi.h"
28 #include "xfs_mount.h" 28 #include "xfs_mount.h"
29 #include "xfs_da_btree.h" 29 #include "xfs_da_btree.h"
30 #include "xfs_bmap_btree.h" 30 #include "xfs_bmap_btree.h"
31 #include "xfs_dir_sf.h" 31 #include "xfs_dir_sf.h"
32 #include "xfs_dir2_sf.h" 32 #include "xfs_dir2_sf.h"
33 #include "xfs_attr_sf.h" 33 #include "xfs_attr_sf.h"
34 #include "xfs_dinode.h" 34 #include "xfs_dinode.h"
35 #include "xfs_inode.h" 35 #include "xfs_inode.h"
36 #include "xfs_inode_item.h" 36 #include "xfs_inode_item.h"
37 #include "xfs_dir_leaf.h" 37 #include "xfs_dir_leaf.h"
38 #include "xfs_dir2_data.h" 38 #include "xfs_dir2_data.h"
39 #include "xfs_dir2_leaf.h" 39 #include "xfs_dir2_leaf.h"
40 #include "xfs_dir2_block.h" 40 #include "xfs_dir2_block.h"
41 #include "xfs_dir2_trace.h" 41 #include "xfs_dir2_trace.h"
42 #include "xfs_error.h" 42 #include "xfs_error.h"
43 43
44 /* 44 /*
45 * Local function prototypes. 45 * Local function prototypes.
46 */ 46 */
47 static void xfs_dir2_block_log_leaf(xfs_trans_t *tp, xfs_dabuf_t *bp, int first, 47 static void xfs_dir2_block_log_leaf(xfs_trans_t *tp, xfs_dabuf_t *bp, int first,
48 int last); 48 int last);
49 static void xfs_dir2_block_log_tail(xfs_trans_t *tp, xfs_dabuf_t *bp); 49 static void xfs_dir2_block_log_tail(xfs_trans_t *tp, xfs_dabuf_t *bp);
50 static int xfs_dir2_block_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **bpp, 50 static int xfs_dir2_block_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **bpp,
51 int *entno); 51 int *entno);
52 static int xfs_dir2_block_sort(const void *a, const void *b); 52 static int xfs_dir2_block_sort(const void *a, const void *b);
53 53
54 /* 54 /*
55 * Add an entry to a block directory. 55 * Add an entry to a block directory.
56 */ 56 */
57 int /* error */ 57 int /* error */
58 xfs_dir2_block_addname( 58 xfs_dir2_block_addname(
59 xfs_da_args_t *args) /* directory op arguments */ 59 xfs_da_args_t *args) /* directory op arguments */
60 { 60 {
61 xfs_dir2_data_free_t *bf; /* bestfree table in block */ 61 xfs_dir2_data_free_t *bf; /* bestfree table in block */
62 xfs_dir2_block_t *block; /* directory block structure */ 62 xfs_dir2_block_t *block; /* directory block structure */
63 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 63 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */
64 xfs_dabuf_t *bp; /* buffer for block */ 64 xfs_dabuf_t *bp; /* buffer for block */
65 xfs_dir2_block_tail_t *btp; /* block tail */ 65 xfs_dir2_block_tail_t *btp; /* block tail */
66 int compact; /* need to compact leaf ents */ 66 int compact; /* need to compact leaf ents */
67 xfs_dir2_data_entry_t *dep; /* block data entry */ 67 xfs_dir2_data_entry_t *dep; /* block data entry */
68 xfs_inode_t *dp; /* directory inode */ 68 xfs_inode_t *dp; /* directory inode */
69 xfs_dir2_data_unused_t *dup; /* block unused entry */ 69 xfs_dir2_data_unused_t *dup; /* block unused entry */
70 int error; /* error return value */ 70 int error; /* error return value */
71 xfs_dir2_data_unused_t *enddup=NULL; /* unused at end of data */ 71 xfs_dir2_data_unused_t *enddup=NULL; /* unused at end of data */
72 xfs_dahash_t hash; /* hash value of found entry */ 72 xfs_dahash_t hash; /* hash value of found entry */
73 int high; /* high index for binary srch */ 73 int high; /* high index for binary srch */
74 int highstale; /* high stale index */ 74 int highstale; /* high stale index */
75 int lfloghigh=0; /* last final leaf to log */ 75 int lfloghigh=0; /* last final leaf to log */
76 int lfloglow=0; /* first final leaf to log */ 76 int lfloglow=0; /* first final leaf to log */
77 int len; /* length of the new entry */ 77 int len; /* length of the new entry */
78 int low; /* low index for binary srch */ 78 int low; /* low index for binary srch */
79 int lowstale; /* low stale index */ 79 int lowstale; /* low stale index */
80 int mid=0; /* midpoint for binary srch */ 80 int mid=0; /* midpoint for binary srch */
81 xfs_mount_t *mp; /* filesystem mount point */ 81 xfs_mount_t *mp; /* filesystem mount point */
82 int needlog; /* need to log header */ 82 int needlog; /* need to log header */
83 int needscan; /* need to rescan freespace */ 83 int needscan; /* need to rescan freespace */
84 xfs_dir2_data_off_t *tagp; /* pointer to tag value */ 84 xfs_dir2_data_off_t *tagp; /* pointer to tag value */
85 xfs_trans_t *tp; /* transaction structure */ 85 xfs_trans_t *tp; /* transaction structure */
86 86
87 xfs_dir2_trace_args("block_addname", args); 87 xfs_dir2_trace_args("block_addname", args);
88 dp = args->dp; 88 dp = args->dp;
89 tp = args->trans; 89 tp = args->trans;
90 mp = dp->i_mount; 90 mp = dp->i_mount;
91 /* 91 /*
92 * Read the (one and only) directory block into dabuf bp. 92 * Read the (one and only) directory block into dabuf bp.
93 */ 93 */
94 if ((error = 94 if ((error =
95 xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) { 95 xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) {
96 return error; 96 return error;
97 } 97 }
98 ASSERT(bp != NULL); 98 ASSERT(bp != NULL);
99 block = bp->data; 99 block = bp->data;
100 /* 100 /*
101 * Check the magic number, corrupted if wrong. 101 * Check the magic number, corrupted if wrong.
102 */ 102 */
103 if (unlikely(INT_GET(block->hdr.magic, ARCH_CONVERT) 103 if (unlikely(be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC)) {
104 != XFS_DIR2_BLOCK_MAGIC)) {
105 XFS_CORRUPTION_ERROR("xfs_dir2_block_addname", 104 XFS_CORRUPTION_ERROR("xfs_dir2_block_addname",
106 XFS_ERRLEVEL_LOW, mp, block); 105 XFS_ERRLEVEL_LOW, mp, block);
107 xfs_da_brelse(tp, bp); 106 xfs_da_brelse(tp, bp);
108 return XFS_ERROR(EFSCORRUPTED); 107 return XFS_ERROR(EFSCORRUPTED);
109 } 108 }
110 len = XFS_DIR2_DATA_ENTSIZE(args->namelen); 109 len = XFS_DIR2_DATA_ENTSIZE(args->namelen);
111 /* 110 /*
112 * Set up pointers to parts of the block. 111 * Set up pointers to parts of the block.
113 */ 112 */
114 bf = block->hdr.bestfree; 113 bf = block->hdr.bestfree;
115 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); 114 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
116 blp = XFS_DIR2_BLOCK_LEAF_P(btp); 115 blp = XFS_DIR2_BLOCK_LEAF_P(btp);
117 /* 116 /*
118 * No stale entries? Need space for entry and new leaf. 117 * No stale entries? Need space for entry and new leaf.
119 */ 118 */
120 if (!btp->stale) { 119 if (!btp->stale) {
121 /* 120 /*
122 * Tag just before the first leaf entry. 121 * Tag just before the first leaf entry.
123 */ 122 */
124 tagp = (xfs_dir2_data_off_t *)blp - 1; 123 tagp = (xfs_dir2_data_off_t *)blp - 1;
125 /* 124 /*
126 * Data object just before the first leaf entry. 125 * Data object just before the first leaf entry.
127 */ 126 */
128 enddup = (xfs_dir2_data_unused_t *)((char *)block + INT_GET(*tagp, ARCH_CONVERT)); 127 enddup = (xfs_dir2_data_unused_t *)((char *)block + INT_GET(*tagp, ARCH_CONVERT));
129 /* 128 /*
130 * If it's not free then can't do this add without cleaning up: 129 * If it's not free then can't do this add without cleaning up:
131 * the space before the first leaf entry needs to be free so it 130 * the space before the first leaf entry needs to be free so it
132 * can be expanded to hold the pointer to the new entry. 131 * can be expanded to hold the pointer to the new entry.
133 */ 132 */
134 if (INT_GET(enddup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG) 133 if (INT_GET(enddup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG)
135 dup = enddup = NULL; 134 dup = enddup = NULL;
136 /* 135 /*
137 * Check out the biggest freespace and see if it's the same one. 136 * Check out the biggest freespace and see if it's the same one.
138 */ 137 */
139 else { 138 else {
140 dup = (xfs_dir2_data_unused_t *) 139 dup = (xfs_dir2_data_unused_t *)
141 ((char *)block + INT_GET(bf[0].offset, ARCH_CONVERT)); 140 ((char *)block + be16_to_cpu(bf[0].offset));
142 if (dup == enddup) { 141 if (dup == enddup) {
143 /* 142 /*
144 * It is the biggest freespace, is it too small 143 * It is the biggest freespace, is it too small
145 * to hold the new leaf too? 144 * to hold the new leaf too?
146 */ 145 */
147 if (INT_GET(dup->length, ARCH_CONVERT) < len + (uint)sizeof(*blp)) { 146 if (INT_GET(dup->length, ARCH_CONVERT) < len + (uint)sizeof(*blp)) {
148 /* 147 /*
149 * Yes, we use the second-largest 148 * Yes, we use the second-largest
150 * entry instead if it works. 149 * entry instead if it works.
151 */ 150 */
152 if (INT_GET(bf[1].length, ARCH_CONVERT) >= len) 151 if (be16_to_cpu(bf[1].length) >= len)
153 dup = (xfs_dir2_data_unused_t *) 152 dup = (xfs_dir2_data_unused_t *)
154 ((char *)block + 153 ((char *)block +
155 INT_GET(bf[1].offset, ARCH_CONVERT)); 154 be16_to_cpu(bf[1].offset));
156 else 155 else
157 dup = NULL; 156 dup = NULL;
158 } 157 }
159 } else { 158 } else {
160 /* 159 /*
161 * Not the same free entry, 160 * Not the same free entry,
162 * just check its length. 161 * just check its length.
163 */ 162 */
164 if (INT_GET(dup->length, ARCH_CONVERT) < len) { 163 if (INT_GET(dup->length, ARCH_CONVERT) < len) {
165 dup = NULL; 164 dup = NULL;
166 } 165 }
167 } 166 }
168 } 167 }
169 compact = 0; 168 compact = 0;
170 } 169 }
171 /* 170 /*
172 * If there are stale entries we'll use one for the leaf. 171 * If there are stale entries we'll use one for the leaf.
173 * Is the biggest entry enough to avoid compaction? 172 * Is the biggest entry enough to avoid compaction?
174 */ 173 */
175 else if (INT_GET(bf[0].length, ARCH_CONVERT) >= len) { 174 else if (be16_to_cpu(bf[0].length) >= len) {
176 dup = (xfs_dir2_data_unused_t *) 175 dup = (xfs_dir2_data_unused_t *)
177 ((char *)block + INT_GET(bf[0].offset, ARCH_CONVERT)); 176 ((char *)block + be16_to_cpu(bf[0].offset));
178 compact = 0; 177 compact = 0;
179 } 178 }
180 /* 179 /*
181 * Will need to compact to make this work. 180 * Will need to compact to make this work.
182 */ 181 */
183 else { 182 else {
184 /* 183 /*
185 * Tag just before the first leaf entry. 184 * Tag just before the first leaf entry.
186 */ 185 */
187 tagp = (xfs_dir2_data_off_t *)blp - 1; 186 tagp = (xfs_dir2_data_off_t *)blp - 1;
188 /* 187 /*
189 * Data object just before the first leaf entry. 188 * Data object just before the first leaf entry.
190 */ 189 */
191 dup = (xfs_dir2_data_unused_t *)((char *)block + INT_GET(*tagp, ARCH_CONVERT)); 190 dup = (xfs_dir2_data_unused_t *)((char *)block + INT_GET(*tagp, ARCH_CONVERT));
192 /* 191 /*
193 * If it's not free then the data will go where the 192 * If it's not free then the data will go where the
194 * leaf data starts now, if it works at all. 193 * leaf data starts now, if it works at all.
195 */ 194 */
196 if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) { 195 if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) {
197 if (INT_GET(dup->length, ARCH_CONVERT) + (INT_GET(btp->stale, ARCH_CONVERT) - 1) * 196 if (INT_GET(dup->length, ARCH_CONVERT) + (INT_GET(btp->stale, ARCH_CONVERT) - 1) *
198 (uint)sizeof(*blp) < len) 197 (uint)sizeof(*blp) < len)
199 dup = NULL; 198 dup = NULL;
200 } else if ((INT_GET(btp->stale, ARCH_CONVERT) - 1) * (uint)sizeof(*blp) < len) 199 } else if ((INT_GET(btp->stale, ARCH_CONVERT) - 1) * (uint)sizeof(*blp) < len)
201 dup = NULL; 200 dup = NULL;
202 else 201 else
203 dup = (xfs_dir2_data_unused_t *)blp; 202 dup = (xfs_dir2_data_unused_t *)blp;
204 compact = 1; 203 compact = 1;
205 } 204 }
206 /* 205 /*
207 * If this isn't a real add, we're done with the buffer. 206 * If this isn't a real add, we're done with the buffer.
208 */ 207 */
209 if (args->justcheck) 208 if (args->justcheck)
210 xfs_da_brelse(tp, bp); 209 xfs_da_brelse(tp, bp);
211 /* 210 /*
212 * If we don't have space for the new entry & leaf ... 211 * If we don't have space for the new entry & leaf ...
213 */ 212 */
214 if (!dup) { 213 if (!dup) {
215 /* 214 /*
216 * Not trying to actually do anything, or don't have 215 * Not trying to actually do anything, or don't have
217 * a space reservation: return no-space. 216 * a space reservation: return no-space.
218 */ 217 */
219 if (args->justcheck || args->total == 0) 218 if (args->justcheck || args->total == 0)
220 return XFS_ERROR(ENOSPC); 219 return XFS_ERROR(ENOSPC);
221 /* 220 /*
222 * Convert to the next larger format. 221 * Convert to the next larger format.
223 * Then add the new entry in that format. 222 * Then add the new entry in that format.
224 */ 223 */
225 error = xfs_dir2_block_to_leaf(args, bp); 224 error = xfs_dir2_block_to_leaf(args, bp);
226 xfs_da_buf_done(bp); 225 xfs_da_buf_done(bp);
227 if (error) 226 if (error)
228 return error; 227 return error;
229 return xfs_dir2_leaf_addname(args); 228 return xfs_dir2_leaf_addname(args);
230 } 229 }
231 /* 230 /*
232 * Just checking, and it would work, so say so. 231 * Just checking, and it would work, so say so.
233 */ 232 */
234 if (args->justcheck) 233 if (args->justcheck)
235 return 0; 234 return 0;
236 needlog = needscan = 0; 235 needlog = needscan = 0;
237 /* 236 /*
238 * If need to compact the leaf entries, do it now. 237 * If need to compact the leaf entries, do it now.
239 * Leave the highest-numbered stale entry stale. 238 * Leave the highest-numbered stale entry stale.
240 * XXX should be the one closest to mid but mid is not yet computed. 239 * XXX should be the one closest to mid but mid is not yet computed.
241 */ 240 */
242 if (compact) { 241 if (compact) {
243 int fromidx; /* source leaf index */ 242 int fromidx; /* source leaf index */
244 int toidx; /* target leaf index */ 243 int toidx; /* target leaf index */
245 244
246 for (fromidx = toidx = INT_GET(btp->count, ARCH_CONVERT) - 1, 245 for (fromidx = toidx = INT_GET(btp->count, ARCH_CONVERT) - 1,
247 highstale = lfloghigh = -1; 246 highstale = lfloghigh = -1;
248 fromidx >= 0; 247 fromidx >= 0;
249 fromidx--) { 248 fromidx--) {
250 if (INT_GET(blp[fromidx].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) { 249 if (INT_GET(blp[fromidx].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) {
251 if (highstale == -1) 250 if (highstale == -1)
252 highstale = toidx; 251 highstale = toidx;
253 else { 252 else {
254 if (lfloghigh == -1) 253 if (lfloghigh == -1)
255 lfloghigh = toidx; 254 lfloghigh = toidx;
256 continue; 255 continue;
257 } 256 }
258 } 257 }
259 if (fromidx < toidx) 258 if (fromidx < toidx)
260 blp[toidx] = blp[fromidx]; 259 blp[toidx] = blp[fromidx];
261 toidx--; 260 toidx--;
262 } 261 }
263 lfloglow = toidx + 1 - (INT_GET(btp->stale, ARCH_CONVERT) - 1); 262 lfloglow = toidx + 1 - (INT_GET(btp->stale, ARCH_CONVERT) - 1);
264 lfloghigh -= INT_GET(btp->stale, ARCH_CONVERT) - 1; 263 lfloghigh -= INT_GET(btp->stale, ARCH_CONVERT) - 1;
265 INT_MOD(btp->count, ARCH_CONVERT, -(INT_GET(btp->stale, ARCH_CONVERT) - 1)); 264 INT_MOD(btp->count, ARCH_CONVERT, -(INT_GET(btp->stale, ARCH_CONVERT) - 1));
266 xfs_dir2_data_make_free(tp, bp, 265 xfs_dir2_data_make_free(tp, bp,
267 (xfs_dir2_data_aoff_t)((char *)blp - (char *)block), 266 (xfs_dir2_data_aoff_t)((char *)blp - (char *)block),
268 (xfs_dir2_data_aoff_t)((INT_GET(btp->stale, ARCH_CONVERT) - 1) * sizeof(*blp)), 267 (xfs_dir2_data_aoff_t)((INT_GET(btp->stale, ARCH_CONVERT) - 1) * sizeof(*blp)),
269 &needlog, &needscan); 268 &needlog, &needscan);
270 blp += INT_GET(btp->stale, ARCH_CONVERT) - 1; 269 blp += INT_GET(btp->stale, ARCH_CONVERT) - 1;
271 INT_SET(btp->stale, ARCH_CONVERT, 1); 270 INT_SET(btp->stale, ARCH_CONVERT, 1);
272 /* 271 /*
273 * If we now need to rebuild the bestfree map, do so. 272 * If we now need to rebuild the bestfree map, do so.
274 * This needs to happen before the next call to use_free. 273 * This needs to happen before the next call to use_free.
275 */ 274 */
276 if (needscan) { 275 if (needscan) {
277 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, 276 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block,
278 &needlog, NULL); 277 &needlog, NULL);
279 needscan = 0; 278 needscan = 0;
280 } 279 }
281 } 280 }
282 /* 281 /*
283 * Set leaf logging boundaries to impossible state. 282 * Set leaf logging boundaries to impossible state.
284 * For the no-stale case they're set explicitly. 283 * For the no-stale case they're set explicitly.
285 */ 284 */
286 else if (INT_GET(btp->stale, ARCH_CONVERT)) { 285 else if (INT_GET(btp->stale, ARCH_CONVERT)) {
287 lfloglow = INT_GET(btp->count, ARCH_CONVERT); 286 lfloglow = INT_GET(btp->count, ARCH_CONVERT);
288 lfloghigh = -1; 287 lfloghigh = -1;
289 } 288 }
290 /* 289 /*
291 * Find the slot that's first lower than our hash value, -1 if none. 290 * Find the slot that's first lower than our hash value, -1 if none.
292 */ 291 */
293 for (low = 0, high = INT_GET(btp->count, ARCH_CONVERT) - 1; low <= high; ) { 292 for (low = 0, high = INT_GET(btp->count, ARCH_CONVERT) - 1; low <= high; ) {
294 mid = (low + high) >> 1; 293 mid = (low + high) >> 1;
295 if ((hash = INT_GET(blp[mid].hashval, ARCH_CONVERT)) == args->hashval) 294 if ((hash = INT_GET(blp[mid].hashval, ARCH_CONVERT)) == args->hashval)
296 break; 295 break;
297 if (hash < args->hashval) 296 if (hash < args->hashval)
298 low = mid + 1; 297 low = mid + 1;
299 else 298 else
300 high = mid - 1; 299 high = mid - 1;
301 } 300 }
302 while (mid >= 0 && INT_GET(blp[mid].hashval, ARCH_CONVERT) >= args->hashval) { 301 while (mid >= 0 && INT_GET(blp[mid].hashval, ARCH_CONVERT) >= args->hashval) {
303 mid--; 302 mid--;
304 } 303 }
305 /* 304 /*
306 * No stale entries, will use enddup space to hold new leaf. 305 * No stale entries, will use enddup space to hold new leaf.
307 */ 306 */
308 if (!btp->stale) { 307 if (!btp->stale) {
309 /* 308 /*
310 * Mark the space needed for the new leaf entry, now in use. 309 * Mark the space needed for the new leaf entry, now in use.
311 */ 310 */
312 xfs_dir2_data_use_free(tp, bp, enddup, 311 xfs_dir2_data_use_free(tp, bp, enddup,
313 (xfs_dir2_data_aoff_t) 312 (xfs_dir2_data_aoff_t)
314 ((char *)enddup - (char *)block + INT_GET(enddup->length, ARCH_CONVERT) - 313 ((char *)enddup - (char *)block + INT_GET(enddup->length, ARCH_CONVERT) -
315 sizeof(*blp)), 314 sizeof(*blp)),
316 (xfs_dir2_data_aoff_t)sizeof(*blp), 315 (xfs_dir2_data_aoff_t)sizeof(*blp),
317 &needlog, &needscan); 316 &needlog, &needscan);
318 /* 317 /*
319 * Update the tail (entry count). 318 * Update the tail (entry count).
320 */ 319 */
321 INT_MOD(btp->count, ARCH_CONVERT, +1); 320 INT_MOD(btp->count, ARCH_CONVERT, +1);
322 /* 321 /*
323 * If we now need to rebuild the bestfree map, do so. 322 * If we now need to rebuild the bestfree map, do so.
324 * This needs to happen before the next call to use_free. 323 * This needs to happen before the next call to use_free.
325 */ 324 */
326 if (needscan) { 325 if (needscan) {
327 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, 326 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block,
328 &needlog, NULL); 327 &needlog, NULL);
329 needscan = 0; 328 needscan = 0;
330 } 329 }
331 /* 330 /*
332 * Adjust pointer to the first leaf entry, we're about to move 331 * Adjust pointer to the first leaf entry, we're about to move
333 * the table up one to open up space for the new leaf entry. 332 * the table up one to open up space for the new leaf entry.
334 * Then adjust our index to match. 333 * Then adjust our index to match.
335 */ 334 */
336 blp--; 335 blp--;
337 mid++; 336 mid++;
338 if (mid) 337 if (mid)
339 memmove(blp, &blp[1], mid * sizeof(*blp)); 338 memmove(blp, &blp[1], mid * sizeof(*blp));
340 lfloglow = 0; 339 lfloglow = 0;
341 lfloghigh = mid; 340 lfloghigh = mid;
342 } 341 }
343 /* 342 /*
344 * Use a stale leaf for our new entry. 343 * Use a stale leaf for our new entry.
345 */ 344 */
346 else { 345 else {
347 for (lowstale = mid; 346 for (lowstale = mid;
348 lowstale >= 0 && 347 lowstale >= 0 &&
349 INT_GET(blp[lowstale].address, ARCH_CONVERT) != XFS_DIR2_NULL_DATAPTR; 348 INT_GET(blp[lowstale].address, ARCH_CONVERT) != XFS_DIR2_NULL_DATAPTR;
350 lowstale--) 349 lowstale--)
351 continue; 350 continue;
352 for (highstale = mid + 1; 351 for (highstale = mid + 1;
353 highstale < INT_GET(btp->count, ARCH_CONVERT) && 352 highstale < INT_GET(btp->count, ARCH_CONVERT) &&
354 INT_GET(blp[highstale].address, ARCH_CONVERT) != XFS_DIR2_NULL_DATAPTR && 353 INT_GET(blp[highstale].address, ARCH_CONVERT) != XFS_DIR2_NULL_DATAPTR &&
355 (lowstale < 0 || mid - lowstale > highstale - mid); 354 (lowstale < 0 || mid - lowstale > highstale - mid);
356 highstale++) 355 highstale++)
357 continue; 356 continue;
358 /* 357 /*
359 * Move entries toward the low-numbered stale entry. 358 * Move entries toward the low-numbered stale entry.
360 */ 359 */
361 if (lowstale >= 0 && 360 if (lowstale >= 0 &&
362 (highstale == INT_GET(btp->count, ARCH_CONVERT) || 361 (highstale == INT_GET(btp->count, ARCH_CONVERT) ||
363 mid - lowstale <= highstale - mid)) { 362 mid - lowstale <= highstale - mid)) {
364 if (mid - lowstale) 363 if (mid - lowstale)
365 memmove(&blp[lowstale], &blp[lowstale + 1], 364 memmove(&blp[lowstale], &blp[lowstale + 1],
366 (mid - lowstale) * sizeof(*blp)); 365 (mid - lowstale) * sizeof(*blp));
367 lfloglow = MIN(lowstale, lfloglow); 366 lfloglow = MIN(lowstale, lfloglow);
368 lfloghigh = MAX(mid, lfloghigh); 367 lfloghigh = MAX(mid, lfloghigh);
369 } 368 }
370 /* 369 /*
371 * Move entries toward the high-numbered stale entry. 370 * Move entries toward the high-numbered stale entry.
372 */ 371 */
373 else { 372 else {
374 ASSERT(highstale < INT_GET(btp->count, ARCH_CONVERT)); 373 ASSERT(highstale < INT_GET(btp->count, ARCH_CONVERT));
375 mid++; 374 mid++;
376 if (highstale - mid) 375 if (highstale - mid)
377 memmove(&blp[mid + 1], &blp[mid], 376 memmove(&blp[mid + 1], &blp[mid],
378 (highstale - mid) * sizeof(*blp)); 377 (highstale - mid) * sizeof(*blp));
379 lfloglow = MIN(mid, lfloglow); 378 lfloglow = MIN(mid, lfloglow);
380 lfloghigh = MAX(highstale, lfloghigh); 379 lfloghigh = MAX(highstale, lfloghigh);
381 } 380 }
382 INT_MOD(btp->stale, ARCH_CONVERT, -1); 381 INT_MOD(btp->stale, ARCH_CONVERT, -1);
383 } 382 }
384 /* 383 /*
385 * Point to the new data entry. 384 * Point to the new data entry.
386 */ 385 */
387 dep = (xfs_dir2_data_entry_t *)dup; 386 dep = (xfs_dir2_data_entry_t *)dup;
388 /* 387 /*
389 * Fill in the leaf entry. 388 * Fill in the leaf entry.
390 */ 389 */
391 INT_SET(blp[mid].hashval, ARCH_CONVERT, args->hashval); 390 INT_SET(blp[mid].hashval, ARCH_CONVERT, args->hashval);
392 INT_SET(blp[mid].address, ARCH_CONVERT, XFS_DIR2_BYTE_TO_DATAPTR(mp, (char *)dep - (char *)block)); 391 INT_SET(blp[mid].address, ARCH_CONVERT, XFS_DIR2_BYTE_TO_DATAPTR(mp, (char *)dep - (char *)block));
393 xfs_dir2_block_log_leaf(tp, bp, lfloglow, lfloghigh); 392 xfs_dir2_block_log_leaf(tp, bp, lfloglow, lfloghigh);
394 /* 393 /*
395 * Mark space for the data entry used. 394 * Mark space for the data entry used.
396 */ 395 */
397 xfs_dir2_data_use_free(tp, bp, dup, 396 xfs_dir2_data_use_free(tp, bp, dup,
398 (xfs_dir2_data_aoff_t)((char *)dup - (char *)block), 397 (xfs_dir2_data_aoff_t)((char *)dup - (char *)block),
399 (xfs_dir2_data_aoff_t)len, &needlog, &needscan); 398 (xfs_dir2_data_aoff_t)len, &needlog, &needscan);
400 /* 399 /*
401 * Create the new data entry. 400 * Create the new data entry.
402 */ 401 */
403 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 402 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
404 dep->namelen = args->namelen; 403 dep->namelen = args->namelen;
405 memcpy(dep->name, args->name, args->namelen); 404 memcpy(dep->name, args->name, args->namelen);
406 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 405 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
407 INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)block)); 406 INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)block));
408 /* 407 /*
409 * Clean up the bestfree array and log the header, tail, and entry. 408 * Clean up the bestfree array and log the header, tail, and entry.
410 */ 409 */
411 if (needscan) 410 if (needscan)
412 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog, 411 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog,
413 NULL); 412 NULL);
414 if (needlog) 413 if (needlog)
415 xfs_dir2_data_log_header(tp, bp); 414 xfs_dir2_data_log_header(tp, bp);
416 xfs_dir2_block_log_tail(tp, bp); 415 xfs_dir2_block_log_tail(tp, bp);
417 xfs_dir2_data_log_entry(tp, bp, dep); 416 xfs_dir2_data_log_entry(tp, bp, dep);
418 xfs_dir2_data_check(dp, bp); 417 xfs_dir2_data_check(dp, bp);
419 xfs_da_buf_done(bp); 418 xfs_da_buf_done(bp);
420 return 0; 419 return 0;
421 } 420 }
422 421
423 /* 422 /*
424 * Readdir for block directories. 423 * Readdir for block directories.
425 */ 424 */
426 int /* error */ 425 int /* error */
427 xfs_dir2_block_getdents( 426 xfs_dir2_block_getdents(
428 xfs_trans_t *tp, /* transaction (NULL) */ 427 xfs_trans_t *tp, /* transaction (NULL) */
429 xfs_inode_t *dp, /* incore inode */ 428 xfs_inode_t *dp, /* incore inode */
430 uio_t *uio, /* caller's buffer control */ 429 uio_t *uio, /* caller's buffer control */
431 int *eofp, /* eof reached? (out) */ 430 int *eofp, /* eof reached? (out) */
432 xfs_dirent_t *dbp, /* caller's buffer */ 431 xfs_dirent_t *dbp, /* caller's buffer */
433 xfs_dir2_put_t put) /* abi's formatting function */ 432 xfs_dir2_put_t put) /* abi's formatting function */
434 { 433 {
435 xfs_dir2_block_t *block; /* directory block structure */ 434 xfs_dir2_block_t *block; /* directory block structure */
436 xfs_dabuf_t *bp; /* buffer for block */ 435 xfs_dabuf_t *bp; /* buffer for block */
437 xfs_dir2_block_tail_t *btp; /* block tail */ 436 xfs_dir2_block_tail_t *btp; /* block tail */
438 xfs_dir2_data_entry_t *dep; /* block data entry */ 437 xfs_dir2_data_entry_t *dep; /* block data entry */
439 xfs_dir2_data_unused_t *dup; /* block unused entry */ 438 xfs_dir2_data_unused_t *dup; /* block unused entry */
440 char *endptr; /* end of the data entries */ 439 char *endptr; /* end of the data entries */
441 int error; /* error return value */ 440 int error; /* error return value */
442 xfs_mount_t *mp; /* filesystem mount point */ 441 xfs_mount_t *mp; /* filesystem mount point */
443 xfs_dir2_put_args_t p; /* arg package for put rtn */ 442 xfs_dir2_put_args_t p; /* arg package for put rtn */
444 char *ptr; /* current data entry */ 443 char *ptr; /* current data entry */
445 int wantoff; /* starting block offset */ 444 int wantoff; /* starting block offset */
446 445
447 mp = dp->i_mount; 446 mp = dp->i_mount;
448 /* 447 /*
449 * If the block number in the offset is out of range, we're done. 448 * If the block number in the offset is out of range, we're done.
450 */ 449 */
451 if (XFS_DIR2_DATAPTR_TO_DB(mp, uio->uio_offset) > mp->m_dirdatablk) { 450 if (XFS_DIR2_DATAPTR_TO_DB(mp, uio->uio_offset) > mp->m_dirdatablk) {
452 *eofp = 1; 451 *eofp = 1;
453 return 0; 452 return 0;
454 } 453 }
455 /* 454 /*
456 * Can't read the block, give up, else get dabuf in bp. 455 * Can't read the block, give up, else get dabuf in bp.
457 */ 456 */
458 if ((error = 457 if ((error =
459 xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) { 458 xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) {
460 return error; 459 return error;
461 } 460 }
462 ASSERT(bp != NULL); 461 ASSERT(bp != NULL);
463 /* 462 /*
464 * Extract the byte offset we start at from the seek pointer. 463 * Extract the byte offset we start at from the seek pointer.
465 * We'll skip entries before this. 464 * We'll skip entries before this.
466 */ 465 */
467 wantoff = XFS_DIR2_DATAPTR_TO_OFF(mp, uio->uio_offset); 466 wantoff = XFS_DIR2_DATAPTR_TO_OFF(mp, uio->uio_offset);
468 block = bp->data; 467 block = bp->data;
469 xfs_dir2_data_check(dp, bp); 468 xfs_dir2_data_check(dp, bp);
470 /* 469 /*
471 * Set up values for the loop. 470 * Set up values for the loop.
472 */ 471 */
473 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); 472 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
474 ptr = (char *)block->u; 473 ptr = (char *)block->u;
475 endptr = (char *)XFS_DIR2_BLOCK_LEAF_P(btp); 474 endptr = (char *)XFS_DIR2_BLOCK_LEAF_P(btp);
476 p.dbp = dbp; 475 p.dbp = dbp;
477 p.put = put; 476 p.put = put;
478 p.uio = uio; 477 p.uio = uio;
479 /* 478 /*
480 * Loop over the data portion of the block. 479 * Loop over the data portion of the block.
481 * Each object is a real entry (dep) or an unused one (dup). 480 * Each object is a real entry (dep) or an unused one (dup).
482 */ 481 */
483 while (ptr < endptr) { 482 while (ptr < endptr) {
484 dup = (xfs_dir2_data_unused_t *)ptr; 483 dup = (xfs_dir2_data_unused_t *)ptr;
485 /* 484 /*
486 * Unused, skip it. 485 * Unused, skip it.
487 */ 486 */
488 if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) { 487 if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) {
489 ptr += INT_GET(dup->length, ARCH_CONVERT); 488 ptr += INT_GET(dup->length, ARCH_CONVERT);
490 continue; 489 continue;
491 } 490 }
492 491
493 dep = (xfs_dir2_data_entry_t *)ptr; 492 dep = (xfs_dir2_data_entry_t *)ptr;
494 493
495 /* 494 /*
496 * Bump pointer for the next iteration. 495 * Bump pointer for the next iteration.
497 */ 496 */
498 ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen); 497 ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
499 /* 498 /*
500 * The entry is before the desired starting point, skip it. 499 * The entry is before the desired starting point, skip it.
501 */ 500 */
502 if ((char *)dep - (char *)block < wantoff) 501 if ((char *)dep - (char *)block < wantoff)
503 continue; 502 continue;
504 /* 503 /*
505 * Set up argument structure for put routine. 504 * Set up argument structure for put routine.
506 */ 505 */
507 p.namelen = dep->namelen; 506 p.namelen = dep->namelen;
508 507
509 p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, 508 p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
510 ptr - (char *)block); 509 ptr - (char *)block);
511 p.ino = INT_GET(dep->inumber, ARCH_CONVERT); 510 p.ino = INT_GET(dep->inumber, ARCH_CONVERT);
512 #if XFS_BIG_INUMS 511 #if XFS_BIG_INUMS
513 p.ino += mp->m_inoadd; 512 p.ino += mp->m_inoadd;
514 #endif 513 #endif
515 p.name = (char *)dep->name; 514 p.name = (char *)dep->name;
516 515
517 /* 516 /*
518 * Put the entry in the caller's buffer. 517 * Put the entry in the caller's buffer.
519 */ 518 */
520 error = p.put(&p); 519 error = p.put(&p);
521 520
522 /* 521 /*
523 * If it didn't fit, set the final offset to here & return. 522 * If it didn't fit, set the final offset to here & return.
524 */ 523 */
525 if (!p.done) { 524 if (!p.done) {
526 uio->uio_offset = 525 uio->uio_offset =
527 XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, 526 XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
528 (char *)dep - (char *)block); 527 (char *)dep - (char *)block);
529 xfs_da_brelse(tp, bp); 528 xfs_da_brelse(tp, bp);
530 return error; 529 return error;
531 } 530 }
532 } 531 }
533 532
534 /* 533 /*
535 * Reached the end of the block. 534 * Reached the end of the block.
536 * Set the offset to a nonexistent block 1 and return. 535 * Set the offset to a nonexistent block 1 and return.
537 */ 536 */
538 *eofp = 1; 537 *eofp = 1;
539 538
540 uio->uio_offset = 539 uio->uio_offset =
541 XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk + 1, 0); 540 XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk + 1, 0);
542 541
543 xfs_da_brelse(tp, bp); 542 xfs_da_brelse(tp, bp);
544 543
545 return 0; 544 return 0;
546 } 545 }
547 546
548 /* 547 /*
549 * Log leaf entries from the block. 548 * Log leaf entries from the block.
550 */ 549 */
551 static void 550 static void
552 xfs_dir2_block_log_leaf( 551 xfs_dir2_block_log_leaf(
553 xfs_trans_t *tp, /* transaction structure */ 552 xfs_trans_t *tp, /* transaction structure */
554 xfs_dabuf_t *bp, /* block buffer */ 553 xfs_dabuf_t *bp, /* block buffer */
555 int first, /* index of first logged leaf */ 554 int first, /* index of first logged leaf */
556 int last) /* index of last logged leaf */ 555 int last) /* index of last logged leaf */
557 { 556 {
558 xfs_dir2_block_t *block; /* directory block structure */ 557 xfs_dir2_block_t *block; /* directory block structure */
559 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 558 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */
560 xfs_dir2_block_tail_t *btp; /* block tail */ 559 xfs_dir2_block_tail_t *btp; /* block tail */
561 xfs_mount_t *mp; /* filesystem mount point */ 560 xfs_mount_t *mp; /* filesystem mount point */
562 561
563 mp = tp->t_mountp; 562 mp = tp->t_mountp;
564 block = bp->data; 563 block = bp->data;
565 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); 564 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
566 blp = XFS_DIR2_BLOCK_LEAF_P(btp); 565 blp = XFS_DIR2_BLOCK_LEAF_P(btp);
567 xfs_da_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)block), 566 xfs_da_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)block),
568 (uint)((char *)&blp[last + 1] - (char *)block - 1)); 567 (uint)((char *)&blp[last + 1] - (char *)block - 1));
569 } 568 }
570 569
571 /* 570 /*
572 * Log the block tail. 571 * Log the block tail.
573 */ 572 */
574 static void 573 static void
575 xfs_dir2_block_log_tail( 574 xfs_dir2_block_log_tail(
576 xfs_trans_t *tp, /* transaction structure */ 575 xfs_trans_t *tp, /* transaction structure */
577 xfs_dabuf_t *bp) /* block buffer */ 576 xfs_dabuf_t *bp) /* block buffer */
578 { 577 {
579 xfs_dir2_block_t *block; /* directory block structure */ 578 xfs_dir2_block_t *block; /* directory block structure */
580 xfs_dir2_block_tail_t *btp; /* block tail */ 579 xfs_dir2_block_tail_t *btp; /* block tail */
581 xfs_mount_t *mp; /* filesystem mount point */ 580 xfs_mount_t *mp; /* filesystem mount point */
582 581
583 mp = tp->t_mountp; 582 mp = tp->t_mountp;
584 block = bp->data; 583 block = bp->data;
585 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); 584 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
586 xfs_da_log_buf(tp, bp, (uint)((char *)btp - (char *)block), 585 xfs_da_log_buf(tp, bp, (uint)((char *)btp - (char *)block),
587 (uint)((char *)(btp + 1) - (char *)block - 1)); 586 (uint)((char *)(btp + 1) - (char *)block - 1));
588 } 587 }
589 588
590 /* 589 /*
591 * Look up an entry in the block. This is the external routine, 590 * Look up an entry in the block. This is the external routine,
592 * xfs_dir2_block_lookup_int does the real work. 591 * xfs_dir2_block_lookup_int does the real work.
593 */ 592 */
594 int /* error */ 593 int /* error */
595 xfs_dir2_block_lookup( 594 xfs_dir2_block_lookup(
596 xfs_da_args_t *args) /* dir lookup arguments */ 595 xfs_da_args_t *args) /* dir lookup arguments */
597 { 596 {
598 xfs_dir2_block_t *block; /* block structure */ 597 xfs_dir2_block_t *block; /* block structure */
599 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 598 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */
600 xfs_dabuf_t *bp; /* block buffer */ 599 xfs_dabuf_t *bp; /* block buffer */
601 xfs_dir2_block_tail_t *btp; /* block tail */ 600 xfs_dir2_block_tail_t *btp; /* block tail */
602 xfs_dir2_data_entry_t *dep; /* block data entry */ 601 xfs_dir2_data_entry_t *dep; /* block data entry */
603 xfs_inode_t *dp; /* incore inode */ 602 xfs_inode_t *dp; /* incore inode */
604 int ent; /* entry index */ 603 int ent; /* entry index */
605 int error; /* error return value */ 604 int error; /* error return value */
606 xfs_mount_t *mp; /* filesystem mount point */ 605 xfs_mount_t *mp; /* filesystem mount point */
607 606
608 xfs_dir2_trace_args("block_lookup", args); 607 xfs_dir2_trace_args("block_lookup", args);
609 /* 608 /*
610 * Get the buffer, look up the entry. 609 * Get the buffer, look up the entry.
611 * If not found (ENOENT) then return, have no buffer. 610 * If not found (ENOENT) then return, have no buffer.
612 */ 611 */
613 if ((error = xfs_dir2_block_lookup_int(args, &bp, &ent))) 612 if ((error = xfs_dir2_block_lookup_int(args, &bp, &ent)))
614 return error; 613 return error;
615 dp = args->dp; 614 dp = args->dp;
616 mp = dp->i_mount; 615 mp = dp->i_mount;
617 block = bp->data; 616 block = bp->data;
618 xfs_dir2_data_check(dp, bp); 617 xfs_dir2_data_check(dp, bp);
619 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); 618 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
620 blp = XFS_DIR2_BLOCK_LEAF_P(btp); 619 blp = XFS_DIR2_BLOCK_LEAF_P(btp);
621 /* 620 /*
622 * Get the offset from the leaf entry, to point to the data. 621 * Get the offset from the leaf entry, to point to the data.
623 */ 622 */
624 dep = (xfs_dir2_data_entry_t *) 623 dep = (xfs_dir2_data_entry_t *)
625 ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(blp[ent].address, ARCH_CONVERT))); 624 ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(blp[ent].address, ARCH_CONVERT)));
626 /* 625 /*
627 * Fill in inode number, release the block. 626 * Fill in inode number, release the block.
628 */ 627 */
629 args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); 628 args->inumber = INT_GET(dep->inumber, ARCH_CONVERT);
630 xfs_da_brelse(args->trans, bp); 629 xfs_da_brelse(args->trans, bp);
631 return XFS_ERROR(EEXIST); 630 return XFS_ERROR(EEXIST);
632 } 631 }
633 632
634 /* 633 /*
635 * Internal block lookup routine. 634 * Internal block lookup routine.
636 */ 635 */
637 static int /* error */ 636 static int /* error */
638 xfs_dir2_block_lookup_int( 637 xfs_dir2_block_lookup_int(
639 xfs_da_args_t *args, /* dir lookup arguments */ 638 xfs_da_args_t *args, /* dir lookup arguments */
640 xfs_dabuf_t **bpp, /* returned block buffer */ 639 xfs_dabuf_t **bpp, /* returned block buffer */
641 int *entno) /* returned entry number */ 640 int *entno) /* returned entry number */
642 { 641 {
643 xfs_dir2_dataptr_t addr; /* data entry address */ 642 xfs_dir2_dataptr_t addr; /* data entry address */
644 xfs_dir2_block_t *block; /* block structure */ 643 xfs_dir2_block_t *block; /* block structure */
645 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 644 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */
646 xfs_dabuf_t *bp; /* block buffer */ 645 xfs_dabuf_t *bp; /* block buffer */
647 xfs_dir2_block_tail_t *btp; /* block tail */ 646 xfs_dir2_block_tail_t *btp; /* block tail */
648 xfs_dir2_data_entry_t *dep; /* block data entry */ 647 xfs_dir2_data_entry_t *dep; /* block data entry */
649 xfs_inode_t *dp; /* incore inode */ 648 xfs_inode_t *dp; /* incore inode */
650 int error; /* error return value */ 649 int error; /* error return value */
651 xfs_dahash_t hash; /* found hash value */ 650 xfs_dahash_t hash; /* found hash value */
652 int high; /* binary search high index */ 651 int high; /* binary search high index */
653 int low; /* binary search low index */ 652 int low; /* binary search low index */
654 int mid; /* binary search current idx */ 653 int mid; /* binary search current idx */
655 xfs_mount_t *mp; /* filesystem mount point */ 654 xfs_mount_t *mp; /* filesystem mount point */
656 xfs_trans_t *tp; /* transaction pointer */ 655 xfs_trans_t *tp; /* transaction pointer */
657 656
658 dp = args->dp; 657 dp = args->dp;
659 tp = args->trans; 658 tp = args->trans;
660 mp = dp->i_mount; 659 mp = dp->i_mount;
661 /* 660 /*
662 * Read the buffer, return error if we can't get it. 661 * Read the buffer, return error if we can't get it.
663 */ 662 */
664 if ((error = 663 if ((error =
665 xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) { 664 xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) {
666 return error; 665 return error;
667 } 666 }
668 ASSERT(bp != NULL); 667 ASSERT(bp != NULL);
669 block = bp->data; 668 block = bp->data;
670 xfs_dir2_data_check(dp, bp); 669 xfs_dir2_data_check(dp, bp);
671 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); 670 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
672 blp = XFS_DIR2_BLOCK_LEAF_P(btp); 671 blp = XFS_DIR2_BLOCK_LEAF_P(btp);
673 /* 672 /*
674 * Loop doing a binary search for our hash value. 673 * Loop doing a binary search for our hash value.
675 * Find our entry, ENOENT if it's not there. 674 * Find our entry, ENOENT if it's not there.
676 */ 675 */
677 for (low = 0, high = INT_GET(btp->count, ARCH_CONVERT) - 1; ; ) { 676 for (low = 0, high = INT_GET(btp->count, ARCH_CONVERT) - 1; ; ) {
678 ASSERT(low <= high); 677 ASSERT(low <= high);
679 mid = (low + high) >> 1; 678 mid = (low + high) >> 1;
680 if ((hash = INT_GET(blp[mid].hashval, ARCH_CONVERT)) == args->hashval) 679 if ((hash = INT_GET(blp[mid].hashval, ARCH_CONVERT)) == args->hashval)
681 break; 680 break;
682 if (hash < args->hashval) 681 if (hash < args->hashval)
683 low = mid + 1; 682 low = mid + 1;
684 else 683 else
685 high = mid - 1; 684 high = mid - 1;
686 if (low > high) { 685 if (low > high) {
687 ASSERT(args->oknoent); 686 ASSERT(args->oknoent);
688 xfs_da_brelse(tp, bp); 687 xfs_da_brelse(tp, bp);
689 return XFS_ERROR(ENOENT); 688 return XFS_ERROR(ENOENT);
690 } 689 }
691 } 690 }
692 /* 691 /*
693 * Back up to the first one with the right hash value. 692 * Back up to the first one with the right hash value.
694 */ 693 */
695 while (mid > 0 && INT_GET(blp[mid - 1].hashval, ARCH_CONVERT) == args->hashval) { 694 while (mid > 0 && INT_GET(blp[mid - 1].hashval, ARCH_CONVERT) == args->hashval) {
696 mid--; 695 mid--;
697 } 696 }
698 /* 697 /*
699 * Now loop forward through all the entries with the 698 * Now loop forward through all the entries with the
700 * right hash value looking for our name. 699 * right hash value looking for our name.
701 */ 700 */
702 do { 701 do {
703 if ((addr = INT_GET(blp[mid].address, ARCH_CONVERT)) == XFS_DIR2_NULL_DATAPTR) 702 if ((addr = INT_GET(blp[mid].address, ARCH_CONVERT)) == XFS_DIR2_NULL_DATAPTR)
704 continue; 703 continue;
705 /* 704 /*
706 * Get pointer to the entry from the leaf. 705 * Get pointer to the entry from the leaf.
707 */ 706 */
708 dep = (xfs_dir2_data_entry_t *) 707 dep = (xfs_dir2_data_entry_t *)
709 ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, addr)); 708 ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, addr));
710 /* 709 /*
711 * Compare, if it's right give back buffer & entry number. 710 * Compare, if it's right give back buffer & entry number.
712 */ 711 */
713 if (dep->namelen == args->namelen && 712 if (dep->namelen == args->namelen &&
714 dep->name[0] == args->name[0] && 713 dep->name[0] == args->name[0] &&
715 memcmp(dep->name, args->name, args->namelen) == 0) { 714 memcmp(dep->name, args->name, args->namelen) == 0) {
716 *bpp = bp; 715 *bpp = bp;
717 *entno = mid; 716 *entno = mid;
718 return 0; 717 return 0;
719 } 718 }
720 } while (++mid < INT_GET(btp->count, ARCH_CONVERT) && INT_GET(blp[mid].hashval, ARCH_CONVERT) == hash); 719 } while (++mid < INT_GET(btp->count, ARCH_CONVERT) && INT_GET(blp[mid].hashval, ARCH_CONVERT) == hash);
721 /* 720 /*
722 * No match, release the buffer and return ENOENT. 721 * No match, release the buffer and return ENOENT.
723 */ 722 */
724 ASSERT(args->oknoent); 723 ASSERT(args->oknoent);
725 xfs_da_brelse(tp, bp); 724 xfs_da_brelse(tp, bp);
726 return XFS_ERROR(ENOENT); 725 return XFS_ERROR(ENOENT);
727 } 726 }
728 727
729 /* 728 /*
730 * Remove an entry from a block format directory. 729 * Remove an entry from a block format directory.
731 * If that makes the block small enough to fit in shortform, transform it. 730 * If that makes the block small enough to fit in shortform, transform it.
732 */ 731 */
733 int /* error */ 732 int /* error */
734 xfs_dir2_block_removename( 733 xfs_dir2_block_removename(
735 xfs_da_args_t *args) /* directory operation args */ 734 xfs_da_args_t *args) /* directory operation args */
736 { 735 {
737 xfs_dir2_block_t *block; /* block structure */ 736 xfs_dir2_block_t *block; /* block structure */
738 xfs_dir2_leaf_entry_t *blp; /* block leaf pointer */ 737 xfs_dir2_leaf_entry_t *blp; /* block leaf pointer */
739 xfs_dabuf_t *bp; /* block buffer */ 738 xfs_dabuf_t *bp; /* block buffer */
740 xfs_dir2_block_tail_t *btp; /* block tail */ 739 xfs_dir2_block_tail_t *btp; /* block tail */
741 xfs_dir2_data_entry_t *dep; /* block data entry */ 740 xfs_dir2_data_entry_t *dep; /* block data entry */
742 xfs_inode_t *dp; /* incore inode */ 741 xfs_inode_t *dp; /* incore inode */
743 int ent; /* block leaf entry index */ 742 int ent; /* block leaf entry index */
744 int error; /* error return value */ 743 int error; /* error return value */
745 xfs_mount_t *mp; /* filesystem mount point */ 744 xfs_mount_t *mp; /* filesystem mount point */
746 int needlog; /* need to log block header */ 745 int needlog; /* need to log block header */
747 int needscan; /* need to fixup bestfree */ 746 int needscan; /* need to fixup bestfree */
748 xfs_dir2_sf_hdr_t sfh; /* shortform header */ 747 xfs_dir2_sf_hdr_t sfh; /* shortform header */
749 int size; /* shortform size */ 748 int size; /* shortform size */
750 xfs_trans_t *tp; /* transaction pointer */ 749 xfs_trans_t *tp; /* transaction pointer */
751 750
752 xfs_dir2_trace_args("block_removename", args); 751 xfs_dir2_trace_args("block_removename", args);
753 /* 752 /*
754 * Look up the entry in the block. Gets the buffer and entry index. 753 * Look up the entry in the block. Gets the buffer and entry index.
755 * It will always be there, the vnodeops level does a lookup first. 754 * It will always be there, the vnodeops level does a lookup first.
756 */ 755 */
757 if ((error = xfs_dir2_block_lookup_int(args, &bp, &ent))) { 756 if ((error = xfs_dir2_block_lookup_int(args, &bp, &ent))) {
758 return error; 757 return error;
759 } 758 }
760 dp = args->dp; 759 dp = args->dp;
761 tp = args->trans; 760 tp = args->trans;
762 mp = dp->i_mount; 761 mp = dp->i_mount;
763 block = bp->data; 762 block = bp->data;
764 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); 763 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
765 blp = XFS_DIR2_BLOCK_LEAF_P(btp); 764 blp = XFS_DIR2_BLOCK_LEAF_P(btp);
766 /* 765 /*
767 * Point to the data entry using the leaf entry. 766 * Point to the data entry using the leaf entry.
768 */ 767 */
769 dep = (xfs_dir2_data_entry_t *) 768 dep = (xfs_dir2_data_entry_t *)
770 ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(blp[ent].address, ARCH_CONVERT))); 769 ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(blp[ent].address, ARCH_CONVERT)));
771 /* 770 /*
772 * Mark the data entry's space free. 771 * Mark the data entry's space free.
773 */ 772 */
774 needlog = needscan = 0; 773 needlog = needscan = 0;
775 xfs_dir2_data_make_free(tp, bp, 774 xfs_dir2_data_make_free(tp, bp,
776 (xfs_dir2_data_aoff_t)((char *)dep - (char *)block), 775 (xfs_dir2_data_aoff_t)((char *)dep - (char *)block),
777 XFS_DIR2_DATA_ENTSIZE(dep->namelen), &needlog, &needscan); 776 XFS_DIR2_DATA_ENTSIZE(dep->namelen), &needlog, &needscan);
778 /* 777 /*
779 * Fix up the block tail. 778 * Fix up the block tail.
780 */ 779 */
781 INT_MOD(btp->stale, ARCH_CONVERT, +1); 780 INT_MOD(btp->stale, ARCH_CONVERT, +1);
782 xfs_dir2_block_log_tail(tp, bp); 781 xfs_dir2_block_log_tail(tp, bp);
783 /* 782 /*
784 * Remove the leaf entry by marking it stale. 783 * Remove the leaf entry by marking it stale.
785 */ 784 */
786 INT_SET(blp[ent].address, ARCH_CONVERT, XFS_DIR2_NULL_DATAPTR); 785 INT_SET(blp[ent].address, ARCH_CONVERT, XFS_DIR2_NULL_DATAPTR);
787 xfs_dir2_block_log_leaf(tp, bp, ent, ent); 786 xfs_dir2_block_log_leaf(tp, bp, ent, ent);
788 /* 787 /*
789 * Fix up bestfree, log the header if necessary. 788 * Fix up bestfree, log the header if necessary.
790 */ 789 */
791 if (needscan) 790 if (needscan)
792 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog, 791 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog,
793 NULL); 792 NULL);
794 if (needlog) 793 if (needlog)
795 xfs_dir2_data_log_header(tp, bp); 794 xfs_dir2_data_log_header(tp, bp);
796 xfs_dir2_data_check(dp, bp); 795 xfs_dir2_data_check(dp, bp);
797 /* 796 /*
798 * See if the size as a shortform is good enough. 797 * See if the size as a shortform is good enough.
799 */ 798 */
800 if ((size = xfs_dir2_block_sfsize(dp, block, &sfh)) > 799 if ((size = xfs_dir2_block_sfsize(dp, block, &sfh)) >
801 XFS_IFORK_DSIZE(dp)) { 800 XFS_IFORK_DSIZE(dp)) {
802 xfs_da_buf_done(bp); 801 xfs_da_buf_done(bp);
803 return 0; 802 return 0;
804 } 803 }
805 /* 804 /*
806 * If it works, do the conversion. 805 * If it works, do the conversion.
807 */ 806 */
808 return xfs_dir2_block_to_sf(args, bp, size, &sfh); 807 return xfs_dir2_block_to_sf(args, bp, size, &sfh);
809 } 808 }
810 809
811 /* 810 /*
812 * Replace an entry in a V2 block directory. 811 * Replace an entry in a V2 block directory.
813 * Change the inode number to the new value. 812 * Change the inode number to the new value.
814 */ 813 */
815 int /* error */ 814 int /* error */
816 xfs_dir2_block_replace( 815 xfs_dir2_block_replace(
817 xfs_da_args_t *args) /* directory operation args */ 816 xfs_da_args_t *args) /* directory operation args */
818 { 817 {
819 xfs_dir2_block_t *block; /* block structure */ 818 xfs_dir2_block_t *block; /* block structure */
820 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 819 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */
821 xfs_dabuf_t *bp; /* block buffer */ 820 xfs_dabuf_t *bp; /* block buffer */
822 xfs_dir2_block_tail_t *btp; /* block tail */ 821 xfs_dir2_block_tail_t *btp; /* block tail */
823 xfs_dir2_data_entry_t *dep; /* block data entry */ 822 xfs_dir2_data_entry_t *dep; /* block data entry */
824 xfs_inode_t *dp; /* incore inode */ 823 xfs_inode_t *dp; /* incore inode */
825 int ent; /* leaf entry index */ 824 int ent; /* leaf entry index */
826 int error; /* error return value */ 825 int error; /* error return value */
827 xfs_mount_t *mp; /* filesystem mount point */ 826 xfs_mount_t *mp; /* filesystem mount point */
828 827
829 xfs_dir2_trace_args("block_replace", args); 828 xfs_dir2_trace_args("block_replace", args);
830 /* 829 /*
831 * Lookup the entry in the directory. Get buffer and entry index. 830 * Lookup the entry in the directory. Get buffer and entry index.
832 * This will always succeed since the caller has already done a lookup. 831 * This will always succeed since the caller has already done a lookup.
833 */ 832 */
834 if ((error = xfs_dir2_block_lookup_int(args, &bp, &ent))) { 833 if ((error = xfs_dir2_block_lookup_int(args, &bp, &ent))) {
835 return error; 834 return error;
836 } 835 }
837 dp = args->dp; 836 dp = args->dp;
838 mp = dp->i_mount; 837 mp = dp->i_mount;
839 block = bp->data; 838 block = bp->data;
840 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); 839 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
841 blp = XFS_DIR2_BLOCK_LEAF_P(btp); 840 blp = XFS_DIR2_BLOCK_LEAF_P(btp);
842 /* 841 /*
843 * Point to the data entry we need to change. 842 * Point to the data entry we need to change.
844 */ 843 */
845 dep = (xfs_dir2_data_entry_t *) 844 dep = (xfs_dir2_data_entry_t *)
846 ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(blp[ent].address, ARCH_CONVERT))); 845 ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(blp[ent].address, ARCH_CONVERT)));
847 ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) != args->inumber); 846 ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) != args->inumber);
848 /* 847 /*
849 * Change the inode number to the new value. 848 * Change the inode number to the new value.
850 */ 849 */
851 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 850 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
852 xfs_dir2_data_log_entry(args->trans, bp, dep); 851 xfs_dir2_data_log_entry(args->trans, bp, dep);
853 xfs_dir2_data_check(dp, bp); 852 xfs_dir2_data_check(dp, bp);
854 xfs_da_buf_done(bp); 853 xfs_da_buf_done(bp);
855 return 0; 854 return 0;
856 } 855 }
857 856
858 /* 857 /*
859 * Qsort comparison routine for the block leaf entries. 858 * Qsort comparison routine for the block leaf entries.
860 */ 859 */
861 static int /* sort order */ 860 static int /* sort order */
862 xfs_dir2_block_sort( 861 xfs_dir2_block_sort(
863 const void *a, /* first leaf entry */ 862 const void *a, /* first leaf entry */
864 const void *b) /* second leaf entry */ 863 const void *b) /* second leaf entry */
865 { 864 {
866 const xfs_dir2_leaf_entry_t *la; /* first leaf entry */ 865 const xfs_dir2_leaf_entry_t *la; /* first leaf entry */
867 const xfs_dir2_leaf_entry_t *lb; /* second leaf entry */ 866 const xfs_dir2_leaf_entry_t *lb; /* second leaf entry */
868 867
869 la = a; 868 la = a;
870 lb = b; 869 lb = b;
871 return INT_GET(la->hashval, ARCH_CONVERT) < INT_GET(lb->hashval, ARCH_CONVERT) ? -1 : 870 return INT_GET(la->hashval, ARCH_CONVERT) < INT_GET(lb->hashval, ARCH_CONVERT) ? -1 :
872 (INT_GET(la->hashval, ARCH_CONVERT) > INT_GET(lb->hashval, ARCH_CONVERT) ? 1 : 0); 871 (INT_GET(la->hashval, ARCH_CONVERT) > INT_GET(lb->hashval, ARCH_CONVERT) ? 1 : 0);
873 } 872 }
874 873
875 /* 874 /*
876 * Convert a V2 leaf directory to a V2 block directory if possible. 875 * Convert a V2 leaf directory to a V2 block directory if possible.
877 */ 876 */
878 int /* error */ 877 int /* error */
879 xfs_dir2_leaf_to_block( 878 xfs_dir2_leaf_to_block(
880 xfs_da_args_t *args, /* operation arguments */ 879 xfs_da_args_t *args, /* operation arguments */
881 xfs_dabuf_t *lbp, /* leaf buffer */ 880 xfs_dabuf_t *lbp, /* leaf buffer */
882 xfs_dabuf_t *dbp) /* data buffer */ 881 xfs_dabuf_t *dbp) /* data buffer */
883 { 882 {
884 xfs_dir2_data_off_t *bestsp; /* leaf bests table */ 883 xfs_dir2_data_off_t *bestsp; /* leaf bests table */
885 xfs_dir2_block_t *block; /* block structure */ 884 xfs_dir2_block_t *block; /* block structure */
886 xfs_dir2_block_tail_t *btp; /* block tail */ 885 xfs_dir2_block_tail_t *btp; /* block tail */
887 xfs_inode_t *dp; /* incore directory inode */ 886 xfs_inode_t *dp; /* incore directory inode */
888 xfs_dir2_data_unused_t *dup; /* unused data entry */ 887 xfs_dir2_data_unused_t *dup; /* unused data entry */
889 int error; /* error return value */ 888 int error; /* error return value */
890 int from; /* leaf from index */ 889 int from; /* leaf from index */
891 xfs_dir2_leaf_t *leaf; /* leaf structure */ 890 xfs_dir2_leaf_t *leaf; /* leaf structure */
892 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 891 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
893 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 892 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
894 xfs_mount_t *mp; /* file system mount point */ 893 xfs_mount_t *mp; /* file system mount point */
895 int needlog; /* need to log data header */ 894 int needlog; /* need to log data header */
896 int needscan; /* need to scan for bestfree */ 895 int needscan; /* need to scan for bestfree */
897 xfs_dir2_sf_hdr_t sfh; /* shortform header */ 896 xfs_dir2_sf_hdr_t sfh; /* shortform header */
898 int size; /* bytes used */ 897 int size; /* bytes used */
899 xfs_dir2_data_off_t *tagp; /* end of entry (tag) */ 898 xfs_dir2_data_off_t *tagp; /* end of entry (tag) */
900 int to; /* block/leaf to index */ 899 int to; /* block/leaf to index */
901 xfs_trans_t *tp; /* transaction pointer */ 900 xfs_trans_t *tp; /* transaction pointer */
902 901
903 xfs_dir2_trace_args_bb("leaf_to_block", args, lbp, dbp); 902 xfs_dir2_trace_args_bb("leaf_to_block", args, lbp, dbp);
904 dp = args->dp; 903 dp = args->dp;
905 tp = args->trans; 904 tp = args->trans;
906 mp = dp->i_mount; 905 mp = dp->i_mount;
907 leaf = lbp->data; 906 leaf = lbp->data;
908 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC); 907 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC);
909 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); 908 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
910 /* 909 /*
911 * If there are data blocks other than the first one, take this 910 * If there are data blocks other than the first one, take this
912 * opportunity to remove trailing empty data blocks that may have 911 * opportunity to remove trailing empty data blocks that may have
913 * been left behind during no-space-reservation operations. 912 * been left behind during no-space-reservation operations.
914 * These will show up in the leaf bests table. 913 * These will show up in the leaf bests table.
915 */ 914 */
916 while (dp->i_d.di_size > mp->m_dirblksize) { 915 while (dp->i_d.di_size > mp->m_dirblksize) {
917 bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); 916 bestsp = XFS_DIR2_LEAF_BESTS_P(ltp);
918 if (INT_GET(bestsp[INT_GET(ltp->bestcount, ARCH_CONVERT) - 1], ARCH_CONVERT) == 917 if (INT_GET(bestsp[INT_GET(ltp->bestcount, ARCH_CONVERT) - 1], ARCH_CONVERT) ==
919 mp->m_dirblksize - (uint)sizeof(block->hdr)) { 918 mp->m_dirblksize - (uint)sizeof(block->hdr)) {
920 if ((error = 919 if ((error =
921 xfs_dir2_leaf_trim_data(args, lbp, 920 xfs_dir2_leaf_trim_data(args, lbp,
922 (xfs_dir2_db_t)(INT_GET(ltp->bestcount, ARCH_CONVERT) - 1)))) 921 (xfs_dir2_db_t)(INT_GET(ltp->bestcount, ARCH_CONVERT) - 1))))
923 goto out; 922 goto out;
924 } else { 923 } else {
925 error = 0; 924 error = 0;
926 goto out; 925 goto out;
927 } 926 }
928 } 927 }
929 /* 928 /*
930 * Read the data block if we don't already have it, give up if it fails. 929 * Read the data block if we don't already have it, give up if it fails.
931 */ 930 */
932 if (dbp == NULL && 931 if (dbp == NULL &&
933 (error = xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &dbp, 932 (error = xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &dbp,
934 XFS_DATA_FORK))) { 933 XFS_DATA_FORK))) {
935 goto out; 934 goto out;
936 } 935 }
937 block = dbp->data; 936 block = dbp->data;
938 ASSERT(INT_GET(block->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC); 937 ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_DATA_MAGIC);
939 /* 938 /*
940 * Size of the "leaf" area in the block. 939 * Size of the "leaf" area in the block.
941 */ 940 */
942 size = (uint)sizeof(block->tail) + 941 size = (uint)sizeof(block->tail) +
943 (uint)sizeof(*lep) * (INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT)); 942 (uint)sizeof(*lep) * (INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT));
944 /* 943 /*
945 * Look at the last data entry. 944 * Look at the last data entry.
946 */ 945 */
947 tagp = (xfs_dir2_data_off_t *)((char *)block + mp->m_dirblksize) - 1; 946 tagp = (xfs_dir2_data_off_t *)((char *)block + mp->m_dirblksize) - 1;
948 dup = (xfs_dir2_data_unused_t *)((char *)block + INT_GET(*tagp, ARCH_CONVERT)); 947 dup = (xfs_dir2_data_unused_t *)((char *)block + INT_GET(*tagp, ARCH_CONVERT));
949 /* 948 /*
950 * If it's not free or is too short we can't do it. 949 * If it's not free or is too short we can't do it.
951 */ 950 */
952 if (INT_GET(dup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG || INT_GET(dup->length, ARCH_CONVERT) < size) { 951 if (INT_GET(dup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG || INT_GET(dup->length, ARCH_CONVERT) < size) {
953 error = 0; 952 error = 0;
954 goto out; 953 goto out;
955 } 954 }
956 /* 955 /*
957 * Start converting it to block form. 956 * Start converting it to block form.
958 */ 957 */
959 INT_SET(block->hdr.magic, ARCH_CONVERT, XFS_DIR2_BLOCK_MAGIC); 958 block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC);
960 needlog = 1; 959 needlog = 1;
961 needscan = 0; 960 needscan = 0;
962 /* 961 /*
963 * Use up the space at the end of the block (blp/btp). 962 * Use up the space at the end of the block (blp/btp).
964 */ 963 */
965 xfs_dir2_data_use_free(tp, dbp, dup, mp->m_dirblksize - size, size, 964 xfs_dir2_data_use_free(tp, dbp, dup, mp->m_dirblksize - size, size,
966 &needlog, &needscan); 965 &needlog, &needscan);
967 /* 966 /*
968 * Initialize the block tail. 967 * Initialize the block tail.
969 */ 968 */
970 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); 969 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
971 INT_SET(btp->count, ARCH_CONVERT, INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT)); 970 INT_SET(btp->count, ARCH_CONVERT, INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT));
972 btp->stale = 0; 971 btp->stale = 0;
973 xfs_dir2_block_log_tail(tp, dbp); 972 xfs_dir2_block_log_tail(tp, dbp);
974 /* 973 /*
975 * Initialize the block leaf area. We compact out stale entries. 974 * Initialize the block leaf area. We compact out stale entries.
976 */ 975 */
977 lep = XFS_DIR2_BLOCK_LEAF_P(btp); 976 lep = XFS_DIR2_BLOCK_LEAF_P(btp);
978 for (from = to = 0; from < INT_GET(leaf->hdr.count, ARCH_CONVERT); from++) { 977 for (from = to = 0; from < INT_GET(leaf->hdr.count, ARCH_CONVERT); from++) {
979 if (INT_GET(leaf->ents[from].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) 978 if (INT_GET(leaf->ents[from].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
980 continue; 979 continue;
981 lep[to++] = leaf->ents[from]; 980 lep[to++] = leaf->ents[from];
982 } 981 }
983 ASSERT(to == INT_GET(btp->count, ARCH_CONVERT)); 982 ASSERT(to == INT_GET(btp->count, ARCH_CONVERT));
984 xfs_dir2_block_log_leaf(tp, dbp, 0, INT_GET(btp->count, ARCH_CONVERT) - 1); 983 xfs_dir2_block_log_leaf(tp, dbp, 0, INT_GET(btp->count, ARCH_CONVERT) - 1);
985 /* 984 /*
986 * Scan the bestfree if we need it and log the data block header. 985 * Scan the bestfree if we need it and log the data block header.
987 */ 986 */
988 if (needscan) 987 if (needscan)
989 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog, 988 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog,
990 NULL); 989 NULL);
991 if (needlog) 990 if (needlog)
992 xfs_dir2_data_log_header(tp, dbp); 991 xfs_dir2_data_log_header(tp, dbp);
993 /* 992 /*
994 * Pitch the old leaf block. 993 * Pitch the old leaf block.
995 */ 994 */
996 error = xfs_da_shrink_inode(args, mp->m_dirleafblk, lbp); 995 error = xfs_da_shrink_inode(args, mp->m_dirleafblk, lbp);
997 lbp = NULL; 996 lbp = NULL;
998 if (error) { 997 if (error) {
999 goto out; 998 goto out;
1000 } 999 }
1001 /* 1000 /*
1002 * Now see if the resulting block can be shrunken to shortform. 1001 * Now see if the resulting block can be shrunken to shortform.
1003 */ 1002 */
1004 if ((size = xfs_dir2_block_sfsize(dp, block, &sfh)) > 1003 if ((size = xfs_dir2_block_sfsize(dp, block, &sfh)) >
1005 XFS_IFORK_DSIZE(dp)) { 1004 XFS_IFORK_DSIZE(dp)) {
1006 error = 0; 1005 error = 0;
1007 goto out; 1006 goto out;
1008 } 1007 }
1009 return xfs_dir2_block_to_sf(args, dbp, size, &sfh); 1008 return xfs_dir2_block_to_sf(args, dbp, size, &sfh);
1010 out: 1009 out:
1011 if (lbp) 1010 if (lbp)
1012 xfs_da_buf_done(lbp); 1011 xfs_da_buf_done(lbp);
1013 if (dbp) 1012 if (dbp)
1014 xfs_da_buf_done(dbp); 1013 xfs_da_buf_done(dbp);
1015 return error; 1014 return error;
1016 } 1015 }
1017 1016
1018 /* 1017 /*
1019 * Convert the shortform directory to block form. 1018 * Convert the shortform directory to block form.
1020 */ 1019 */
1021 int /* error */ 1020 int /* error */
1022 xfs_dir2_sf_to_block( 1021 xfs_dir2_sf_to_block(
1023 xfs_da_args_t *args) /* operation arguments */ 1022 xfs_da_args_t *args) /* operation arguments */
1024 { 1023 {
1025 xfs_dir2_db_t blkno; /* dir-relative block # (0) */ 1024 xfs_dir2_db_t blkno; /* dir-relative block # (0) */
1026 xfs_dir2_block_t *block; /* block structure */ 1025 xfs_dir2_block_t *block; /* block structure */
1027 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 1026 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */
1028 xfs_dabuf_t *bp; /* block buffer */ 1027 xfs_dabuf_t *bp; /* block buffer */
1029 xfs_dir2_block_tail_t *btp; /* block tail pointer */ 1028 xfs_dir2_block_tail_t *btp; /* block tail pointer */
1030 char *buf; /* sf buffer */ 1029 char *buf; /* sf buffer */
1031 int buf_len; 1030 int buf_len;
1032 xfs_dir2_data_entry_t *dep; /* data entry pointer */ 1031 xfs_dir2_data_entry_t *dep; /* data entry pointer */
1033 xfs_inode_t *dp; /* incore directory inode */ 1032 xfs_inode_t *dp; /* incore directory inode */
1034 int dummy; /* trash */ 1033 int dummy; /* trash */
1035 xfs_dir2_data_unused_t *dup; /* unused entry pointer */ 1034 xfs_dir2_data_unused_t *dup; /* unused entry pointer */
1036 int endoffset; /* end of data objects */ 1035 int endoffset; /* end of data objects */
1037 int error; /* error return value */ 1036 int error; /* error return value */
1038 int i; /* index */ 1037 int i; /* index */
1039 xfs_mount_t *mp; /* filesystem mount point */ 1038 xfs_mount_t *mp; /* filesystem mount point */
1040 int needlog; /* need to log block header */ 1039 int needlog; /* need to log block header */
1041 int needscan; /* need to scan block freespc */ 1040 int needscan; /* need to scan block freespc */
1042 int newoffset; /* offset from current entry */ 1041 int newoffset; /* offset from current entry */
1043 int offset; /* target block offset */ 1042 int offset; /* target block offset */
1044 xfs_dir2_sf_entry_t *sfep; /* sf entry pointer */ 1043 xfs_dir2_sf_entry_t *sfep; /* sf entry pointer */
1045 xfs_dir2_sf_t *sfp; /* shortform structure */ 1044 xfs_dir2_sf_t *sfp; /* shortform structure */
1046 xfs_dir2_data_off_t *tagp; /* end of data entry */ 1045 xfs_dir2_data_off_t *tagp; /* end of data entry */
1047 xfs_trans_t *tp; /* transaction pointer */ 1046 xfs_trans_t *tp; /* transaction pointer */
1048 1047
1049 xfs_dir2_trace_args("sf_to_block", args); 1048 xfs_dir2_trace_args("sf_to_block", args);
1050 dp = args->dp; 1049 dp = args->dp;
1051 tp = args->trans; 1050 tp = args->trans;
1052 mp = dp->i_mount; 1051 mp = dp->i_mount;
1053 ASSERT(dp->i_df.if_flags & XFS_IFINLINE); 1052 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
1054 /* 1053 /*
1055 * Bomb out if the shortform directory is way too short. 1054 * Bomb out if the shortform directory is way too short.
1056 */ 1055 */
1057 if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { 1056 if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
1058 ASSERT(XFS_FORCED_SHUTDOWN(mp)); 1057 ASSERT(XFS_FORCED_SHUTDOWN(mp));
1059 return XFS_ERROR(EIO); 1058 return XFS_ERROR(EIO);
1060 } 1059 }
1061 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); 1060 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
1062 ASSERT(dp->i_df.if_u1.if_data != NULL); 1061 ASSERT(dp->i_df.if_u1.if_data != NULL);
1063 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 1062 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
1064 ASSERT(dp->i_d.di_size >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count)); 1063 ASSERT(dp->i_d.di_size >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count));
1065 /* 1064 /*
1066 * Copy the directory into the stack buffer. 1065 * Copy the directory into the stack buffer.
1067 * Then pitch the incore inode data so we can make extents. 1066 * Then pitch the incore inode data so we can make extents.
1068 */ 1067 */
1069 1068
1070 buf_len = dp->i_df.if_bytes; 1069 buf_len = dp->i_df.if_bytes;
1071 buf = kmem_alloc(dp->i_df.if_bytes, KM_SLEEP); 1070 buf = kmem_alloc(dp->i_df.if_bytes, KM_SLEEP);
1072 1071
1073 memcpy(buf, sfp, dp->i_df.if_bytes); 1072 memcpy(buf, sfp, dp->i_df.if_bytes);
1074 xfs_idata_realloc(dp, -dp->i_df.if_bytes, XFS_DATA_FORK); 1073 xfs_idata_realloc(dp, -dp->i_df.if_bytes, XFS_DATA_FORK);
1075 dp->i_d.di_size = 0; 1074 dp->i_d.di_size = 0;
1076 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); 1075 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
1077 /* 1076 /*
1078 * Reset pointer - old sfp is gone. 1077 * Reset pointer - old sfp is gone.
1079 */ 1078 */
1080 sfp = (xfs_dir2_sf_t *)buf; 1079 sfp = (xfs_dir2_sf_t *)buf;
1081 /* 1080 /*
1082 * Add block 0 to the inode. 1081 * Add block 0 to the inode.
1083 */ 1082 */
1084 error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, &blkno); 1083 error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, &blkno);
1085 if (error) { 1084 if (error) {
1086 kmem_free(buf, buf_len); 1085 kmem_free(buf, buf_len);
1087 return error; 1086 return error;
1088 } 1087 }
1089 /* 1088 /*
1090 * Initialize the data block. 1089 * Initialize the data block.
1091 */ 1090 */
1092 error = xfs_dir2_data_init(args, blkno, &bp); 1091 error = xfs_dir2_data_init(args, blkno, &bp);
1093 if (error) { 1092 if (error) {
1094 kmem_free(buf, buf_len); 1093 kmem_free(buf, buf_len);
1095 return error; 1094 return error;
1096 } 1095 }
1097 block = bp->data; 1096 block = bp->data;
1098 INT_SET(block->hdr.magic, ARCH_CONVERT, XFS_DIR2_BLOCK_MAGIC); 1097 block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC);
1099 /* 1098 /*
1100 * Compute size of block "tail" area. 1099 * Compute size of block "tail" area.
1101 */ 1100 */
1102 i = (uint)sizeof(*btp) + 1101 i = (uint)sizeof(*btp) +
1103 (INT_GET(sfp->hdr.count, ARCH_CONVERT) + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t); 1102 (INT_GET(sfp->hdr.count, ARCH_CONVERT) + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t);
1104 /* 1103 /*
1105 * The whole thing is initialized to free by the init routine. 1104 * The whole thing is initialized to free by the init routine.
1106 * Say we're using the leaf and tail area. 1105 * Say we're using the leaf and tail area.
1107 */ 1106 */
1108 dup = (xfs_dir2_data_unused_t *)block->u; 1107 dup = (xfs_dir2_data_unused_t *)block->u;
1109 needlog = needscan = 0; 1108 needlog = needscan = 0;
1110 xfs_dir2_data_use_free(tp, bp, dup, mp->m_dirblksize - i, i, &needlog, 1109 xfs_dir2_data_use_free(tp, bp, dup, mp->m_dirblksize - i, i, &needlog,
1111 &needscan); 1110 &needscan);
1112 ASSERT(needscan == 0); 1111 ASSERT(needscan == 0);
1113 /* 1112 /*
1114 * Fill in the tail. 1113 * Fill in the tail.
1115 */ 1114 */
1116 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); 1115 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
1117 INT_SET(btp->count, ARCH_CONVERT, INT_GET(sfp->hdr.count, ARCH_CONVERT) + 2); /* ., .. */ 1116 INT_SET(btp->count, ARCH_CONVERT, INT_GET(sfp->hdr.count, ARCH_CONVERT) + 2); /* ., .. */
1118 btp->stale = 0; 1117 btp->stale = 0;
1119 blp = XFS_DIR2_BLOCK_LEAF_P(btp); 1118 blp = XFS_DIR2_BLOCK_LEAF_P(btp);
1120 endoffset = (uint)((char *)blp - (char *)block); 1119 endoffset = (uint)((char *)blp - (char *)block);
1121 /* 1120 /*
1122 * Remove the freespace, we'll manage it. 1121 * Remove the freespace, we'll manage it.
1123 */ 1122 */
1124 xfs_dir2_data_use_free(tp, bp, dup, 1123 xfs_dir2_data_use_free(tp, bp, dup,
1125 (xfs_dir2_data_aoff_t)((char *)dup - (char *)block), 1124 (xfs_dir2_data_aoff_t)((char *)dup - (char *)block),
1126 INT_GET(dup->length, ARCH_CONVERT), &needlog, &needscan); 1125 INT_GET(dup->length, ARCH_CONVERT), &needlog, &needscan);
1127 /* 1126 /*
1128 * Create entry for . 1127 * Create entry for .
1129 */ 1128 */
1130 dep = (xfs_dir2_data_entry_t *) 1129 dep = (xfs_dir2_data_entry_t *)
1131 ((char *)block + XFS_DIR2_DATA_DOT_OFFSET); 1130 ((char *)block + XFS_DIR2_DATA_DOT_OFFSET);
1132 INT_SET(dep->inumber, ARCH_CONVERT, dp->i_ino); 1131 INT_SET(dep->inumber, ARCH_CONVERT, dp->i_ino);
1133 dep->namelen = 1; 1132 dep->namelen = 1;
1134 dep->name[0] = '.'; 1133 dep->name[0] = '.';
1135 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 1134 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
1136 INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)block)); 1135 INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)block));
1137 xfs_dir2_data_log_entry(tp, bp, dep); 1136 xfs_dir2_data_log_entry(tp, bp, dep);
1138 INT_SET(blp[0].hashval, ARCH_CONVERT, xfs_dir_hash_dot); 1137 INT_SET(blp[0].hashval, ARCH_CONVERT, xfs_dir_hash_dot);
1139 INT_SET(blp[0].address, ARCH_CONVERT, XFS_DIR2_BYTE_TO_DATAPTR(mp, (char *)dep - (char *)block)); 1138 INT_SET(blp[0].address, ARCH_CONVERT, XFS_DIR2_BYTE_TO_DATAPTR(mp, (char *)dep - (char *)block));
1140 /* 1139 /*
1141 * Create entry for .. 1140 * Create entry for ..
1142 */ 1141 */
1143 dep = (xfs_dir2_data_entry_t *) 1142 dep = (xfs_dir2_data_entry_t *)
1144 ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET); 1143 ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET);
1145 INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent)); 1144 INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent));
1146 dep->namelen = 2; 1145 dep->namelen = 2;
1147 dep->name[0] = dep->name[1] = '.'; 1146 dep->name[0] = dep->name[1] = '.';
1148 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 1147 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
1149 INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)block)); 1148 INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)block));
1150 xfs_dir2_data_log_entry(tp, bp, dep); 1149 xfs_dir2_data_log_entry(tp, bp, dep);
1151 INT_SET(blp[1].hashval, ARCH_CONVERT, xfs_dir_hash_dotdot); 1150 INT_SET(blp[1].hashval, ARCH_CONVERT, xfs_dir_hash_dotdot);
1152 INT_SET(blp[1].address, ARCH_CONVERT, XFS_DIR2_BYTE_TO_DATAPTR(mp, (char *)dep - (char *)block)); 1151 INT_SET(blp[1].address, ARCH_CONVERT, XFS_DIR2_BYTE_TO_DATAPTR(mp, (char *)dep - (char *)block));
1153 offset = XFS_DIR2_DATA_FIRST_OFFSET; 1152 offset = XFS_DIR2_DATA_FIRST_OFFSET;
1154 /* 1153 /*
1155 * Loop over existing entries, stuff them in. 1154 * Loop over existing entries, stuff them in.
1156 */ 1155 */
1157 if ((i = 0) == INT_GET(sfp->hdr.count, ARCH_CONVERT)) 1156 if ((i = 0) == INT_GET(sfp->hdr.count, ARCH_CONVERT))
1158 sfep = NULL; 1157 sfep = NULL;
1159 else 1158 else
1160 sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); 1159 sfep = XFS_DIR2_SF_FIRSTENTRY(sfp);
1161 /* 1160 /*
1162 * Need to preserve the existing offset values in the sf directory. 1161 * Need to preserve the existing offset values in the sf directory.
1163 * Insert holes (unused entries) where necessary. 1162 * Insert holes (unused entries) where necessary.
1164 */ 1163 */
1165 while (offset < endoffset) { 1164 while (offset < endoffset) {
1166 /* 1165 /*
1167 * sfep is null when we reach the end of the list. 1166 * sfep is null when we reach the end of the list.
1168 */ 1167 */
1169 if (sfep == NULL) 1168 if (sfep == NULL)
1170 newoffset = endoffset; 1169 newoffset = endoffset;
1171 else 1170 else
1172 newoffset = XFS_DIR2_SF_GET_OFFSET(sfep); 1171 newoffset = XFS_DIR2_SF_GET_OFFSET(sfep);
1173 /* 1172 /*
1174 * There should be a hole here, make one. 1173 * There should be a hole here, make one.
1175 */ 1174 */
1176 if (offset < newoffset) { 1175 if (offset < newoffset) {
1177 dup = (xfs_dir2_data_unused_t *) 1176 dup = (xfs_dir2_data_unused_t *)
1178 ((char *)block + offset); 1177 ((char *)block + offset);
1179 INT_SET(dup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG); 1178 INT_SET(dup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG);
1180 INT_SET(dup->length, ARCH_CONVERT, newoffset - offset); 1179 INT_SET(dup->length, ARCH_CONVERT, newoffset - offset);
1181 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT, 1180 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT,
1182 (xfs_dir2_data_off_t) 1181 (xfs_dir2_data_off_t)
1183 ((char *)dup - (char *)block)); 1182 ((char *)dup - (char *)block));
1184 xfs_dir2_data_log_unused(tp, bp, dup); 1183 xfs_dir2_data_log_unused(tp, bp, dup);
1185 (void)xfs_dir2_data_freeinsert((xfs_dir2_data_t *)block, 1184 (void)xfs_dir2_data_freeinsert((xfs_dir2_data_t *)block,
1186 dup, &dummy); 1185 dup, &dummy);
1187 offset += INT_GET(dup->length, ARCH_CONVERT); 1186 offset += INT_GET(dup->length, ARCH_CONVERT);
1188 continue; 1187 continue;
1189 } 1188 }
1190 /* 1189 /*
1191 * Copy a real entry. 1190 * Copy a real entry.
1192 */ 1191 */
1193 dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset); 1192 dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset);
1194 INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp, 1193 INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp,
1195 XFS_DIR2_SF_INUMBERP(sfep))); 1194 XFS_DIR2_SF_INUMBERP(sfep)));
1196 dep->namelen = sfep->namelen; 1195 dep->namelen = sfep->namelen;
1197 memcpy(dep->name, sfep->name, dep->namelen); 1196 memcpy(dep->name, sfep->name, dep->namelen);
1198 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 1197 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
1199 INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)block)); 1198 INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)block));
1200 xfs_dir2_data_log_entry(tp, bp, dep); 1199 xfs_dir2_data_log_entry(tp, bp, dep);
1201 INT_SET(blp[2 + i].hashval, ARCH_CONVERT, xfs_da_hashname((char *)sfep->name, sfep->namelen)); 1200 INT_SET(blp[2 + i].hashval, ARCH_CONVERT, xfs_da_hashname((char *)sfep->name, sfep->namelen));
1202 INT_SET(blp[2 + i].address, ARCH_CONVERT, XFS_DIR2_BYTE_TO_DATAPTR(mp, 1201 INT_SET(blp[2 + i].address, ARCH_CONVERT, XFS_DIR2_BYTE_TO_DATAPTR(mp,
1203 (char *)dep - (char *)block)); 1202 (char *)dep - (char *)block));
1204 offset = (int)((char *)(tagp + 1) - (char *)block); 1203 offset = (int)((char *)(tagp + 1) - (char *)block);
1205 if (++i == INT_GET(sfp->hdr.count, ARCH_CONVERT)) 1204 if (++i == INT_GET(sfp->hdr.count, ARCH_CONVERT))
1206 sfep = NULL; 1205 sfep = NULL;
1207 else 1206 else
1208 sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep); 1207 sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep);
1209 } 1208 }
1210 /* Done with the temporary buffer */ 1209 /* Done with the temporary buffer */
1211 kmem_free(buf, buf_len); 1210 kmem_free(buf, buf_len);
1212 /* 1211 /*
1213 * Sort the leaf entries by hash value. 1212 * Sort the leaf entries by hash value.
1214 */ 1213 */
1215 xfs_sort(blp, INT_GET(btp->count, ARCH_CONVERT), sizeof(*blp), xfs_dir2_block_sort); 1214 xfs_sort(blp, INT_GET(btp->count, ARCH_CONVERT), sizeof(*blp), xfs_dir2_block_sort);
1216 /* 1215 /*
1217 * Log the leaf entry area and tail. 1216 * Log the leaf entry area and tail.
1218 * Already logged the header in data_init, ignore needlog. 1217 * Already logged the header in data_init, ignore needlog.
1219 */ 1218 */
1220 ASSERT(needscan == 0); 1219 ASSERT(needscan == 0);
1221 xfs_dir2_block_log_leaf(tp, bp, 0, INT_GET(btp->count, ARCH_CONVERT) - 1); 1220 xfs_dir2_block_log_leaf(tp, bp, 0, INT_GET(btp->count, ARCH_CONVERT) - 1);
1222 xfs_dir2_block_log_tail(tp, bp); 1221 xfs_dir2_block_log_tail(tp, bp);
1223 xfs_dir2_data_check(dp, bp); 1222 xfs_dir2_data_check(dp, bp);
1224 xfs_da_buf_done(bp); 1223 xfs_da_buf_done(bp);
1225 return 0; 1224 return 0;
1226 } 1225 }
1227 1226
fs/xfs/xfs_dir2_data.c
1 /* 1 /*
2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 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 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 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, 15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18 #include "xfs.h" 18 #include "xfs.h"
19 #include "xfs_fs.h" 19 #include "xfs_fs.h"
20 #include "xfs_types.h" 20 #include "xfs_types.h"
21 #include "xfs_log.h" 21 #include "xfs_log.h"
22 #include "xfs_inum.h" 22 #include "xfs_inum.h"
23 #include "xfs_trans.h" 23 #include "xfs_trans.h"
24 #include "xfs_sb.h" 24 #include "xfs_sb.h"
25 #include "xfs_dir.h" 25 #include "xfs_dir.h"
26 #include "xfs_dir2.h" 26 #include "xfs_dir2.h"
27 #include "xfs_dmapi.h" 27 #include "xfs_dmapi.h"
28 #include "xfs_mount.h" 28 #include "xfs_mount.h"
29 #include "xfs_da_btree.h" 29 #include "xfs_da_btree.h"
30 #include "xfs_bmap_btree.h" 30 #include "xfs_bmap_btree.h"
31 #include "xfs_dir_sf.h" 31 #include "xfs_dir_sf.h"
32 #include "xfs_dir2_sf.h" 32 #include "xfs_dir2_sf.h"
33 #include "xfs_attr_sf.h" 33 #include "xfs_attr_sf.h"
34 #include "xfs_dinode.h" 34 #include "xfs_dinode.h"
35 #include "xfs_inode.h" 35 #include "xfs_inode.h"
36 #include "xfs_dir_leaf.h" 36 #include "xfs_dir_leaf.h"
37 #include "xfs_dir2_data.h" 37 #include "xfs_dir2_data.h"
38 #include "xfs_dir2_leaf.h" 38 #include "xfs_dir2_leaf.h"
39 #include "xfs_dir2_block.h" 39 #include "xfs_dir2_block.h"
40 #include "xfs_error.h" 40 #include "xfs_error.h"
41 41
42 #ifdef DEBUG 42 #ifdef DEBUG
43 /* 43 /*
44 * Check the consistency of the data block. 44 * Check the consistency of the data block.
45 * The input can also be a block-format directory. 45 * The input can also be a block-format directory.
46 * Pop an assert if we find anything bad. 46 * Pop an assert if we find anything bad.
47 */ 47 */
48 void 48 void
49 xfs_dir2_data_check( 49 xfs_dir2_data_check(
50 xfs_inode_t *dp, /* incore inode pointer */ 50 xfs_inode_t *dp, /* incore inode pointer */
51 xfs_dabuf_t *bp) /* data block's buffer */ 51 xfs_dabuf_t *bp) /* data block's buffer */
52 { 52 {
53 xfs_dir2_dataptr_t addr; /* addr for leaf lookup */ 53 xfs_dir2_dataptr_t addr; /* addr for leaf lookup */
54 xfs_dir2_data_free_t *bf; /* bestfree table */ 54 xfs_dir2_data_free_t *bf; /* bestfree table */
55 xfs_dir2_block_tail_t *btp=NULL; /* block tail */ 55 xfs_dir2_block_tail_t *btp=NULL; /* block tail */
56 int count; /* count of entries found */ 56 int count; /* count of entries found */
57 xfs_dir2_data_t *d; /* data block pointer */ 57 xfs_dir2_data_t *d; /* data block pointer */
58 xfs_dir2_data_entry_t *dep; /* data entry */ 58 xfs_dir2_data_entry_t *dep; /* data entry */
59 xfs_dir2_data_free_t *dfp; /* bestfree entry */ 59 xfs_dir2_data_free_t *dfp; /* bestfree entry */
60 xfs_dir2_data_unused_t *dup; /* unused entry */ 60 xfs_dir2_data_unused_t *dup; /* unused entry */
61 char *endp; /* end of useful data */ 61 char *endp; /* end of useful data */
62 int freeseen; /* mask of bestfrees seen */ 62 int freeseen; /* mask of bestfrees seen */
63 xfs_dahash_t hash; /* hash of current name */ 63 xfs_dahash_t hash; /* hash of current name */
64 int i; /* leaf index */ 64 int i; /* leaf index */
65 int lastfree; /* last entry was unused */ 65 int lastfree; /* last entry was unused */
66 xfs_dir2_leaf_entry_t *lep=NULL; /* block leaf entries */ 66 xfs_dir2_leaf_entry_t *lep=NULL; /* block leaf entries */
67 xfs_mount_t *mp; /* filesystem mount point */ 67 xfs_mount_t *mp; /* filesystem mount point */
68 char *p; /* current data position */ 68 char *p; /* current data position */
69 int stale; /* count of stale leaves */ 69 int stale; /* count of stale leaves */
70 70
71 mp = dp->i_mount; 71 mp = dp->i_mount;
72 d = bp->data; 72 d = bp->data;
73 ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC || 73 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
74 INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); 74 be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
75 bf = d->hdr.bestfree; 75 bf = d->hdr.bestfree;
76 p = (char *)d->u; 76 p = (char *)d->u;
77 if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) { 77 if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
78 btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d); 78 btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d);
79 lep = XFS_DIR2_BLOCK_LEAF_P(btp); 79 lep = XFS_DIR2_BLOCK_LEAF_P(btp);
80 endp = (char *)lep; 80 endp = (char *)lep;
81 } else 81 } else
82 endp = (char *)d + mp->m_dirblksize; 82 endp = (char *)d + mp->m_dirblksize;
83 count = lastfree = freeseen = 0; 83 count = lastfree = freeseen = 0;
84 /* 84 /*
85 * Account for zero bestfree entries. 85 * Account for zero bestfree entries.
86 */ 86 */
87 if (!bf[0].length) { 87 if (!bf[0].length) {
88 ASSERT(!bf[0].offset); 88 ASSERT(!bf[0].offset);
89 freeseen |= 1 << 0; 89 freeseen |= 1 << 0;
90 } 90 }
91 if (!bf[1].length) { 91 if (!bf[1].length) {
92 ASSERT(!bf[1].offset); 92 ASSERT(!bf[1].offset);
93 freeseen |= 1 << 1; 93 freeseen |= 1 << 1;
94 } 94 }
95 if (!bf[2].length) { 95 if (!bf[2].length) {
96 ASSERT(!bf[2].offset); 96 ASSERT(!bf[2].offset);
97 freeseen |= 1 << 2; 97 freeseen |= 1 << 2;
98 } 98 }
99 ASSERT(INT_GET(bf[0].length, ARCH_CONVERT) >= INT_GET(bf[1].length, ARCH_CONVERT)); 99 ASSERT(be16_to_cpu(bf[0].length) >= be16_to_cpu(bf[1].length));
100 ASSERT(INT_GET(bf[1].length, ARCH_CONVERT) >= INT_GET(bf[2].length, ARCH_CONVERT)); 100 ASSERT(be16_to_cpu(bf[1].length) >= be16_to_cpu(bf[2].length));
101 /* 101 /*
102 * Loop over the data/unused entries. 102 * Loop over the data/unused entries.
103 */ 103 */
104 while (p < endp) { 104 while (p < endp) {
105 dup = (xfs_dir2_data_unused_t *)p; 105 dup = (xfs_dir2_data_unused_t *)p;
106 /* 106 /*
107 * If it's unused, look for the space in the bestfree table. 107 * If it's unused, look for the space in the bestfree table.
108 * If we find it, account for that, else make sure it 108 * If we find it, account for that, else make sure it
109 * doesn't need to be there. 109 * doesn't need to be there.
110 */ 110 */
111 if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) { 111 if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) {
112 ASSERT(lastfree == 0); 112 ASSERT(lastfree == 0);
113 ASSERT(INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT) == 113 ASSERT(INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT) ==
114 (char *)dup - (char *)d); 114 (char *)dup - (char *)d);
115 dfp = xfs_dir2_data_freefind(d, dup); 115 dfp = xfs_dir2_data_freefind(d, dup);
116 if (dfp) { 116 if (dfp) {
117 i = (int)(dfp - bf); 117 i = (int)(dfp - bf);
118 ASSERT((freeseen & (1 << i)) == 0); 118 ASSERT((freeseen & (1 << i)) == 0);
119 freeseen |= 1 << i; 119 freeseen |= 1 << i;
120 } else 120 } else {
121 ASSERT(INT_GET(dup->length, ARCH_CONVERT) <= INT_GET(bf[2].length, ARCH_CONVERT)); 121 ASSERT(INT_GET(dup->length, ARCH_CONVERT) <=
122 be16_to_cpu(bf[2].length));
123 }
122 p += INT_GET(dup->length, ARCH_CONVERT); 124 p += INT_GET(dup->length, ARCH_CONVERT);
123 lastfree = 1; 125 lastfree = 1;
124 continue; 126 continue;
125 } 127 }
126 /* 128 /*
127 * It's a real entry. Validate the fields. 129 * It's a real entry. Validate the fields.
128 * If this is a block directory then make sure it's 130 * If this is a block directory then make sure it's
129 * in the leaf section of the block. 131 * in the leaf section of the block.
130 * The linear search is crude but this is DEBUG code. 132 * The linear search is crude but this is DEBUG code.
131 */ 133 */
132 dep = (xfs_dir2_data_entry_t *)p; 134 dep = (xfs_dir2_data_entry_t *)p;
133 ASSERT(dep->namelen != 0); 135 ASSERT(dep->namelen != 0);
134 ASSERT(xfs_dir_ino_validate(mp, INT_GET(dep->inumber, ARCH_CONVERT)) == 0); 136 ASSERT(xfs_dir_ino_validate(mp, INT_GET(dep->inumber, ARCH_CONVERT)) == 0);
135 ASSERT(INT_GET(*XFS_DIR2_DATA_ENTRY_TAG_P(dep), ARCH_CONVERT) == 137 ASSERT(INT_GET(*XFS_DIR2_DATA_ENTRY_TAG_P(dep), ARCH_CONVERT) ==
136 (char *)dep - (char *)d); 138 (char *)dep - (char *)d);
137 count++; 139 count++;
138 lastfree = 0; 140 lastfree = 0;
139 if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) { 141 if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
140 addr = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, 142 addr = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
141 (xfs_dir2_data_aoff_t) 143 (xfs_dir2_data_aoff_t)
142 ((char *)dep - (char *)d)); 144 ((char *)dep - (char *)d));
143 hash = xfs_da_hashname((char *)dep->name, dep->namelen); 145 hash = xfs_da_hashname((char *)dep->name, dep->namelen);
144 for (i = 0; i < INT_GET(btp->count, ARCH_CONVERT); i++) { 146 for (i = 0; i < INT_GET(btp->count, ARCH_CONVERT); i++) {
145 if (INT_GET(lep[i].address, ARCH_CONVERT) == addr && 147 if (INT_GET(lep[i].address, ARCH_CONVERT) == addr &&
146 INT_GET(lep[i].hashval, ARCH_CONVERT) == hash) 148 INT_GET(lep[i].hashval, ARCH_CONVERT) == hash)
147 break; 149 break;
148 } 150 }
149 ASSERT(i < INT_GET(btp->count, ARCH_CONVERT)); 151 ASSERT(i < INT_GET(btp->count, ARCH_CONVERT));
150 } 152 }
151 p += XFS_DIR2_DATA_ENTSIZE(dep->namelen); 153 p += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
152 } 154 }
153 /* 155 /*
154 * Need to have seen all the entries and all the bestfree slots. 156 * Need to have seen all the entries and all the bestfree slots.
155 */ 157 */
156 ASSERT(freeseen == 7); 158 ASSERT(freeseen == 7);
157 if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) { 159 if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
158 for (i = stale = 0; i < INT_GET(btp->count, ARCH_CONVERT); i++) { 160 for (i = stale = 0; i < INT_GET(btp->count, ARCH_CONVERT); i++) {
159 if (INT_GET(lep[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) 161 if (INT_GET(lep[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
160 stale++; 162 stale++;
161 if (i > 0) 163 if (i > 0)
162 ASSERT(INT_GET(lep[i].hashval, ARCH_CONVERT) >= INT_GET(lep[i - 1].hashval, ARCH_CONVERT)); 164 ASSERT(INT_GET(lep[i].hashval, ARCH_CONVERT) >= INT_GET(lep[i - 1].hashval, ARCH_CONVERT));
163 } 165 }
164 ASSERT(count == INT_GET(btp->count, ARCH_CONVERT) - INT_GET(btp->stale, ARCH_CONVERT)); 166 ASSERT(count == INT_GET(btp->count, ARCH_CONVERT) - INT_GET(btp->stale, ARCH_CONVERT));
165 ASSERT(stale == INT_GET(btp->stale, ARCH_CONVERT)); 167 ASSERT(stale == INT_GET(btp->stale, ARCH_CONVERT));
166 } 168 }
167 } 169 }
168 #endif 170 #endif
169 171
170 /* 172 /*
171 * Given a data block and an unused entry from that block, 173 * Given a data block and an unused entry from that block,
172 * return the bestfree entry if any that corresponds to it. 174 * return the bestfree entry if any that corresponds to it.
173 */ 175 */
174 xfs_dir2_data_free_t * 176 xfs_dir2_data_free_t *
175 xfs_dir2_data_freefind( 177 xfs_dir2_data_freefind(
176 xfs_dir2_data_t *d, /* data block */ 178 xfs_dir2_data_t *d, /* data block */
177 xfs_dir2_data_unused_t *dup) /* data unused entry */ 179 xfs_dir2_data_unused_t *dup) /* data unused entry */
178 { 180 {
179 xfs_dir2_data_free_t *dfp; /* bestfree entry */ 181 xfs_dir2_data_free_t *dfp; /* bestfree entry */
180 xfs_dir2_data_aoff_t off; /* offset value needed */ 182 xfs_dir2_data_aoff_t off; /* offset value needed */
181 #if defined(DEBUG) && defined(__KERNEL__) 183 #if defined(DEBUG) && defined(__KERNEL__)
182 int matched; /* matched the value */ 184 int matched; /* matched the value */
183 int seenzero; /* saw a 0 bestfree entry */ 185 int seenzero; /* saw a 0 bestfree entry */
184 #endif 186 #endif
185 187
186 off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)d); 188 off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)d);
187 #if defined(DEBUG) && defined(__KERNEL__) 189 #if defined(DEBUG) && defined(__KERNEL__)
188 /* 190 /*
189 * Validate some consistency in the bestfree table. 191 * Validate some consistency in the bestfree table.
190 * Check order, non-overlapping entries, and if we find the 192 * Check order, non-overlapping entries, and if we find the
191 * one we're looking for it has to be exact. 193 * one we're looking for it has to be exact.
192 */ 194 */
193 ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC || 195 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
194 INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); 196 be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
195 for (dfp = &d->hdr.bestfree[0], seenzero = matched = 0; 197 for (dfp = &d->hdr.bestfree[0], seenzero = matched = 0;
196 dfp < &d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT]; 198 dfp < &d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT];
197 dfp++) { 199 dfp++) {
198 if (!dfp->offset) { 200 if (!dfp->offset) {
199 ASSERT(!dfp->length); 201 ASSERT(!dfp->length);
200 seenzero = 1; 202 seenzero = 1;
201 continue; 203 continue;
202 } 204 }
203 ASSERT(seenzero == 0); 205 ASSERT(seenzero == 0);
204 if (INT_GET(dfp->offset, ARCH_CONVERT) == off) { 206 if (be16_to_cpu(dfp->offset) == off) {
205 matched = 1; 207 matched = 1;
206 ASSERT(INT_GET(dfp->length, ARCH_CONVERT) == INT_GET(dup->length, ARCH_CONVERT)); 208 ASSERT(be16_to_cpu(dfp->length) == INT_GET(dup->length, ARCH_CONVERT));
207 } else if (off < INT_GET(dfp->offset, ARCH_CONVERT)) 209 } else if (off < be16_to_cpu(dfp->offset))
208 ASSERT(off + INT_GET(dup->length, ARCH_CONVERT) <= INT_GET(dfp->offset, ARCH_CONVERT)); 210 ASSERT(off + INT_GET(dup->length, ARCH_CONVERT) <= be16_to_cpu(dfp->offset));
209 else 211 else
210 ASSERT(INT_GET(dfp->offset, ARCH_CONVERT) + INT_GET(dfp->length, ARCH_CONVERT) <= off); 212 ASSERT(be16_to_cpu(dfp->offset) + be16_to_cpu(dfp->length) <= off);
211 ASSERT(matched || INT_GET(dfp->length, ARCH_CONVERT) >= INT_GET(dup->length, ARCH_CONVERT)); 213 ASSERT(matched || be16_to_cpu(dfp->length) >= INT_GET(dup->length, ARCH_CONVERT));
212 if (dfp > &d->hdr.bestfree[0]) 214 if (dfp > &d->hdr.bestfree[0])
213 ASSERT(INT_GET(dfp[-1].length, ARCH_CONVERT) >= INT_GET(dfp[0].length, ARCH_CONVERT)); 215 ASSERT(be16_to_cpu(dfp[-1].length) >= be16_to_cpu(dfp[0].length));
214 } 216 }
215 #endif 217 #endif
216 /* 218 /*
217 * If this is smaller than the smallest bestfree entry, 219 * If this is smaller than the smallest bestfree entry,
218 * it can't be there since they're sorted. 220 * it can't be there since they're sorted.
219 */ 221 */
220 if (INT_GET(dup->length, ARCH_CONVERT) < INT_GET(d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length, ARCH_CONVERT)) 222 if (INT_GET(dup->length, ARCH_CONVERT) <
223 be16_to_cpu(d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length))
221 return NULL; 224 return NULL;
222 /* 225 /*
223 * Look at the three bestfree entries for our guy. 226 * Look at the three bestfree entries for our guy.
224 */ 227 */
225 for (dfp = &d->hdr.bestfree[0]; 228 for (dfp = &d->hdr.bestfree[0];
226 dfp < &d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT]; 229 dfp < &d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT];
227 dfp++) { 230 dfp++) {
228 if (!dfp->offset) 231 if (!dfp->offset)
229 return NULL; 232 return NULL;
230 if (INT_GET(dfp->offset, ARCH_CONVERT) == off) 233 if (be16_to_cpu(dfp->offset) == off)
231 return dfp; 234 return dfp;
232 } 235 }
233 /* 236 /*
234 * Didn't find it. This only happens if there are duplicate lengths. 237 * Didn't find it. This only happens if there are duplicate lengths.
235 */ 238 */
236 return NULL; 239 return NULL;
237 } 240 }
238 241
239 /* 242 /*
240 * Insert an unused-space entry into the bestfree table. 243 * Insert an unused-space entry into the bestfree table.
241 */ 244 */
242 xfs_dir2_data_free_t * /* entry inserted */ 245 xfs_dir2_data_free_t * /* entry inserted */
243 xfs_dir2_data_freeinsert( 246 xfs_dir2_data_freeinsert(
244 xfs_dir2_data_t *d, /* data block pointer */ 247 xfs_dir2_data_t *d, /* data block pointer */
245 xfs_dir2_data_unused_t *dup, /* unused space */ 248 xfs_dir2_data_unused_t *dup, /* unused space */
246 int *loghead) /* log the data header (out) */ 249 int *loghead) /* log the data header (out) */
247 { 250 {
248 xfs_dir2_data_free_t *dfp; /* bestfree table pointer */ 251 xfs_dir2_data_free_t *dfp; /* bestfree table pointer */
249 xfs_dir2_data_free_t new; /* new bestfree entry */ 252 xfs_dir2_data_free_t new; /* new bestfree entry */
250 253
251 #ifdef __KERNEL__ 254 #ifdef __KERNEL__
252 ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC || 255 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
253 INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); 256 be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
254 #endif 257 #endif
255 dfp = d->hdr.bestfree; 258 dfp = d->hdr.bestfree;
256 INT_COPY(new.length, dup->length, ARCH_CONVERT); 259 new.length = dup->length;
257 INT_SET(new.offset, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dup - (char *)d)); 260 new.offset = cpu_to_be16((char *)dup - (char *)d);
258 /* 261 /*
259 * Insert at position 0, 1, or 2; or not at all. 262 * Insert at position 0, 1, or 2; or not at all.
260 */ 263 */
261 if (INT_GET(new.length, ARCH_CONVERT) > INT_GET(dfp[0].length, ARCH_CONVERT)) { 264 if (be16_to_cpu(new.length) > be16_to_cpu(dfp[0].length)) {
262 dfp[2] = dfp[1]; 265 dfp[2] = dfp[1];
263 dfp[1] = dfp[0]; 266 dfp[1] = dfp[0];
264 dfp[0] = new; 267 dfp[0] = new;
265 *loghead = 1; 268 *loghead = 1;
266 return &dfp[0]; 269 return &dfp[0];
267 } 270 }
268 if (INT_GET(new.length, ARCH_CONVERT) > INT_GET(dfp[1].length, ARCH_CONVERT)) { 271 if (be16_to_cpu(new.length) > be16_to_cpu(dfp[1].length)) {
269 dfp[2] = dfp[1]; 272 dfp[2] = dfp[1];
270 dfp[1] = new; 273 dfp[1] = new;
271 *loghead = 1; 274 *loghead = 1;
272 return &dfp[1]; 275 return &dfp[1];
273 } 276 }
274 if (INT_GET(new.length, ARCH_CONVERT) > INT_GET(dfp[2].length, ARCH_CONVERT)) { 277 if (be16_to_cpu(new.length) > be16_to_cpu(dfp[2].length)) {
275 dfp[2] = new; 278 dfp[2] = new;
276 *loghead = 1; 279 *loghead = 1;
277 return &dfp[2]; 280 return &dfp[2];
278 } 281 }
279 return NULL; 282 return NULL;
280 } 283 }
281 284
282 /* 285 /*
283 * Remove a bestfree entry from the table. 286 * Remove a bestfree entry from the table.
284 */ 287 */
285 STATIC void 288 STATIC void
286 xfs_dir2_data_freeremove( 289 xfs_dir2_data_freeremove(
287 xfs_dir2_data_t *d, /* data block pointer */ 290 xfs_dir2_data_t *d, /* data block pointer */
288 xfs_dir2_data_free_t *dfp, /* bestfree entry pointer */ 291 xfs_dir2_data_free_t *dfp, /* bestfree entry pointer */
289 int *loghead) /* out: log data header */ 292 int *loghead) /* out: log data header */
290 { 293 {
291 #ifdef __KERNEL__ 294 #ifdef __KERNEL__
292 ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC || 295 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
293 INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); 296 be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
294 #endif 297 #endif
295 /* 298 /*
296 * It's the first entry, slide the next 2 up. 299 * It's the first entry, slide the next 2 up.
297 */ 300 */
298 if (dfp == &d->hdr.bestfree[0]) { 301 if (dfp == &d->hdr.bestfree[0]) {
299 d->hdr.bestfree[0] = d->hdr.bestfree[1]; 302 d->hdr.bestfree[0] = d->hdr.bestfree[1];
300 d->hdr.bestfree[1] = d->hdr.bestfree[2]; 303 d->hdr.bestfree[1] = d->hdr.bestfree[2];
301 } 304 }
302 /* 305 /*
303 * It's the second entry, slide the 3rd entry up. 306 * It's the second entry, slide the 3rd entry up.
304 */ 307 */
305 else if (dfp == &d->hdr.bestfree[1]) 308 else if (dfp == &d->hdr.bestfree[1])
306 d->hdr.bestfree[1] = d->hdr.bestfree[2]; 309 d->hdr.bestfree[1] = d->hdr.bestfree[2];
307 /* 310 /*
308 * Must be the last entry. 311 * Must be the last entry.
309 */ 312 */
310 else 313 else
311 ASSERT(dfp == &d->hdr.bestfree[2]); 314 ASSERT(dfp == &d->hdr.bestfree[2]);
312 /* 315 /*
313 * Clear the 3rd entry, must be zero now. 316 * Clear the 3rd entry, must be zero now.
314 */ 317 */
315 d->hdr.bestfree[2].length = 0; 318 d->hdr.bestfree[2].length = 0;
316 d->hdr.bestfree[2].offset = 0; 319 d->hdr.bestfree[2].offset = 0;
317 *loghead = 1; 320 *loghead = 1;
318 } 321 }
319 322
320 /* 323 /*
321 * Given a data block, reconstruct its bestfree map. 324 * Given a data block, reconstruct its bestfree map.
322 */ 325 */
323 void 326 void
324 xfs_dir2_data_freescan( 327 xfs_dir2_data_freescan(
325 xfs_mount_t *mp, /* filesystem mount point */ 328 xfs_mount_t *mp, /* filesystem mount point */
326 xfs_dir2_data_t *d, /* data block pointer */ 329 xfs_dir2_data_t *d, /* data block pointer */
327 int *loghead, /* out: log data header */ 330 int *loghead, /* out: log data header */
328 char *aendp) /* in: caller's endp */ 331 char *aendp) /* in: caller's endp */
329 { 332 {
330 xfs_dir2_block_tail_t *btp; /* block tail */ 333 xfs_dir2_block_tail_t *btp; /* block tail */
331 xfs_dir2_data_entry_t *dep; /* active data entry */ 334 xfs_dir2_data_entry_t *dep; /* active data entry */
332 xfs_dir2_data_unused_t *dup; /* unused data entry */ 335 xfs_dir2_data_unused_t *dup; /* unused data entry */
333 char *endp; /* end of block's data */ 336 char *endp; /* end of block's data */
334 char *p; /* current entry pointer */ 337 char *p; /* current entry pointer */
335 338
336 #ifdef __KERNEL__ 339 #ifdef __KERNEL__
337 ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC || 340 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
338 INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); 341 be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
339 #endif 342 #endif
340 /* 343 /*
341 * Start by clearing the table. 344 * Start by clearing the table.
342 */ 345 */
343 memset(d->hdr.bestfree, 0, sizeof(d->hdr.bestfree)); 346 memset(d->hdr.bestfree, 0, sizeof(d->hdr.bestfree));
344 *loghead = 1; 347 *loghead = 1;
345 /* 348 /*
346 * Set up pointers. 349 * Set up pointers.
347 */ 350 */
348 p = (char *)d->u; 351 p = (char *)d->u;
349 if (aendp) 352 if (aendp)
350 endp = aendp; 353 endp = aendp;
351 else if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) { 354 else if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
352 btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d); 355 btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d);
353 endp = (char *)XFS_DIR2_BLOCK_LEAF_P(btp); 356 endp = (char *)XFS_DIR2_BLOCK_LEAF_P(btp);
354 } else 357 } else
355 endp = (char *)d + mp->m_dirblksize; 358 endp = (char *)d + mp->m_dirblksize;
356 /* 359 /*
357 * Loop over the block's entries. 360 * Loop over the block's entries.
358 */ 361 */
359 while (p < endp) { 362 while (p < endp) {
360 dup = (xfs_dir2_data_unused_t *)p; 363 dup = (xfs_dir2_data_unused_t *)p;
361 /* 364 /*
362 * If it's a free entry, insert it. 365 * If it's a free entry, insert it.
363 */ 366 */
364 if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) { 367 if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) {
365 ASSERT((char *)dup - (char *)d == 368 ASSERT((char *)dup - (char *)d ==
366 INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT)); 369 INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT));
367 xfs_dir2_data_freeinsert(d, dup, loghead); 370 xfs_dir2_data_freeinsert(d, dup, loghead);
368 p += INT_GET(dup->length, ARCH_CONVERT); 371 p += INT_GET(dup->length, ARCH_CONVERT);
369 } 372 }
370 /* 373 /*
371 * For active entries, check their tags and skip them. 374 * For active entries, check their tags and skip them.
372 */ 375 */
373 else { 376 else {
374 dep = (xfs_dir2_data_entry_t *)p; 377 dep = (xfs_dir2_data_entry_t *)p;
375 ASSERT((char *)dep - (char *)d == 378 ASSERT((char *)dep - (char *)d ==
376 INT_GET(*XFS_DIR2_DATA_ENTRY_TAG_P(dep), ARCH_CONVERT)); 379 INT_GET(*XFS_DIR2_DATA_ENTRY_TAG_P(dep), ARCH_CONVERT));
377 p += XFS_DIR2_DATA_ENTSIZE(dep->namelen); 380 p += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
378 } 381 }
379 } 382 }
380 } 383 }
381 384
382 /* 385 /*
383 * Initialize a data block at the given block number in the directory. 386 * Initialize a data block at the given block number in the directory.
384 * Give back the buffer for the created block. 387 * Give back the buffer for the created block.
385 */ 388 */
386 int /* error */ 389 int /* error */
387 xfs_dir2_data_init( 390 xfs_dir2_data_init(
388 xfs_da_args_t *args, /* directory operation args */ 391 xfs_da_args_t *args, /* directory operation args */
389 xfs_dir2_db_t blkno, /* logical dir block number */ 392 xfs_dir2_db_t blkno, /* logical dir block number */
390 xfs_dabuf_t **bpp) /* output block buffer */ 393 xfs_dabuf_t **bpp) /* output block buffer */
391 { 394 {
392 xfs_dabuf_t *bp; /* block buffer */ 395 xfs_dabuf_t *bp; /* block buffer */
393 xfs_dir2_data_t *d; /* pointer to block */ 396 xfs_dir2_data_t *d; /* pointer to block */
394 xfs_inode_t *dp; /* incore directory inode */ 397 xfs_inode_t *dp; /* incore directory inode */
395 xfs_dir2_data_unused_t *dup; /* unused entry pointer */ 398 xfs_dir2_data_unused_t *dup; /* unused entry pointer */
396 int error; /* error return value */ 399 int error; /* error return value */
397 int i; /* bestfree index */ 400 int i; /* bestfree index */
398 xfs_mount_t *mp; /* filesystem mount point */ 401 xfs_mount_t *mp; /* filesystem mount point */
399 xfs_trans_t *tp; /* transaction pointer */ 402 xfs_trans_t *tp; /* transaction pointer */
400 int t; /* temp */ 403 int t; /* temp */
401 404
402 dp = args->dp; 405 dp = args->dp;
403 mp = dp->i_mount; 406 mp = dp->i_mount;
404 tp = args->trans; 407 tp = args->trans;
405 /* 408 /*
406 * Get the buffer set up for the block. 409 * Get the buffer set up for the block.
407 */ 410 */
408 error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, blkno), -1, &bp, 411 error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, blkno), -1, &bp,
409 XFS_DATA_FORK); 412 XFS_DATA_FORK);
410 if (error) { 413 if (error) {
411 return error; 414 return error;
412 } 415 }
413 ASSERT(bp != NULL); 416 ASSERT(bp != NULL);
414 /* 417 /*
415 * Initialize the header. 418 * Initialize the header.
416 */ 419 */
417 d = bp->data; 420 d = bp->data;
418 INT_SET(d->hdr.magic, ARCH_CONVERT, XFS_DIR2_DATA_MAGIC); 421 d->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
419 INT_SET(d->hdr.bestfree[0].offset, ARCH_CONVERT, (xfs_dir2_data_off_t)sizeof(d->hdr)); 422 d->hdr.bestfree[0].offset = cpu_to_be16(sizeof(d->hdr));
420 for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) { 423 for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
421 d->hdr.bestfree[i].length = 0; 424 d->hdr.bestfree[i].length = 0;
422 d->hdr.bestfree[i].offset = 0; 425 d->hdr.bestfree[i].offset = 0;
423 } 426 }
424 /* 427 /*
425 * Set up an unused entry for the block's body. 428 * Set up an unused entry for the block's body.
426 */ 429 */
427 dup = &d->u[0].unused; 430 dup = &d->u[0].unused;
428 INT_SET(dup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG); 431 INT_SET(dup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG);
429 432
430 t=mp->m_dirblksize - (uint)sizeof(d->hdr); 433 t=mp->m_dirblksize - (uint)sizeof(d->hdr);
431 INT_SET(d->hdr.bestfree[0].length, ARCH_CONVERT, t); 434 d->hdr.bestfree[0].length = cpu_to_be16(t);
432 INT_SET(dup->length, ARCH_CONVERT, t); 435 INT_SET(dup->length, ARCH_CONVERT, t);
433 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT, 436 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT,
434 (xfs_dir2_data_off_t)((char *)dup - (char *)d)); 437 (xfs_dir2_data_off_t)((char *)dup - (char *)d));
435 /* 438 /*
436 * Log it and return it. 439 * Log it and return it.
437 */ 440 */
438 xfs_dir2_data_log_header(tp, bp); 441 xfs_dir2_data_log_header(tp, bp);
439 xfs_dir2_data_log_unused(tp, bp, dup); 442 xfs_dir2_data_log_unused(tp, bp, dup);
440 *bpp = bp; 443 *bpp = bp;
441 return 0; 444 return 0;
442 } 445 }
443 446
444 /* 447 /*
445 * Log an active data entry from the block. 448 * Log an active data entry from the block.
446 */ 449 */
447 void 450 void
448 xfs_dir2_data_log_entry( 451 xfs_dir2_data_log_entry(
449 xfs_trans_t *tp, /* transaction pointer */ 452 xfs_trans_t *tp, /* transaction pointer */
450 xfs_dabuf_t *bp, /* block buffer */ 453 xfs_dabuf_t *bp, /* block buffer */
451 xfs_dir2_data_entry_t *dep) /* data entry pointer */ 454 xfs_dir2_data_entry_t *dep) /* data entry pointer */
452 { 455 {
453 xfs_dir2_data_t *d; /* data block pointer */ 456 xfs_dir2_data_t *d; /* data block pointer */
454 457
455 d = bp->data; 458 d = bp->data;
456 ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC || 459 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
457 INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); 460 be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
458 xfs_da_log_buf(tp, bp, (uint)((char *)dep - (char *)d), 461 xfs_da_log_buf(tp, bp, (uint)((char *)dep - (char *)d),
459 (uint)((char *)(XFS_DIR2_DATA_ENTRY_TAG_P(dep) + 1) - 462 (uint)((char *)(XFS_DIR2_DATA_ENTRY_TAG_P(dep) + 1) -
460 (char *)d - 1)); 463 (char *)d - 1));
461 } 464 }
462 465
463 /* 466 /*
464 * Log a data block header. 467 * Log a data block header.
465 */ 468 */
466 void 469 void
467 xfs_dir2_data_log_header( 470 xfs_dir2_data_log_header(
468 xfs_trans_t *tp, /* transaction pointer */ 471 xfs_trans_t *tp, /* transaction pointer */
469 xfs_dabuf_t *bp) /* block buffer */ 472 xfs_dabuf_t *bp) /* block buffer */
470 { 473 {
471 xfs_dir2_data_t *d; /* data block pointer */ 474 xfs_dir2_data_t *d; /* data block pointer */
472 475
473 d = bp->data; 476 d = bp->data;
474 ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC || 477 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
475 INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); 478 be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
476 xfs_da_log_buf(tp, bp, (uint)((char *)&d->hdr - (char *)d), 479 xfs_da_log_buf(tp, bp, (uint)((char *)&d->hdr - (char *)d),
477 (uint)(sizeof(d->hdr) - 1)); 480 (uint)(sizeof(d->hdr) - 1));
478 } 481 }
479 482
480 /* 483 /*
481 * Log a data unused entry. 484 * Log a data unused entry.
482 */ 485 */
483 void 486 void
484 xfs_dir2_data_log_unused( 487 xfs_dir2_data_log_unused(
485 xfs_trans_t *tp, /* transaction pointer */ 488 xfs_trans_t *tp, /* transaction pointer */
486 xfs_dabuf_t *bp, /* block buffer */ 489 xfs_dabuf_t *bp, /* block buffer */
487 xfs_dir2_data_unused_t *dup) /* data unused pointer */ 490 xfs_dir2_data_unused_t *dup) /* data unused pointer */
488 { 491 {
489 xfs_dir2_data_t *d; /* data block pointer */ 492 xfs_dir2_data_t *d; /* data block pointer */
490 493
491 d = bp->data; 494 d = bp->data;
492 ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC || 495 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
493 INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); 496 be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
494 /* 497 /*
495 * Log the first part of the unused entry. 498 * Log the first part of the unused entry.
496 */ 499 */
497 xfs_da_log_buf(tp, bp, (uint)((char *)dup - (char *)d), 500 xfs_da_log_buf(tp, bp, (uint)((char *)dup - (char *)d),
498 (uint)((char *)&dup->length + sizeof(dup->length) - 501 (uint)((char *)&dup->length + sizeof(dup->length) -
499 1 - (char *)d)); 502 1 - (char *)d));
500 /* 503 /*
501 * Log the end (tag) of the unused entry. 504 * Log the end (tag) of the unused entry.
502 */ 505 */
503 xfs_da_log_buf(tp, bp, 506 xfs_da_log_buf(tp, bp,
504 (uint)((char *)XFS_DIR2_DATA_UNUSED_TAG_P(dup) - (char *)d), 507 (uint)((char *)XFS_DIR2_DATA_UNUSED_TAG_P(dup) - (char *)d),
505 (uint)((char *)XFS_DIR2_DATA_UNUSED_TAG_P(dup) - (char *)d + 508 (uint)((char *)XFS_DIR2_DATA_UNUSED_TAG_P(dup) - (char *)d +
506 sizeof(xfs_dir2_data_off_t) - 1)); 509 sizeof(xfs_dir2_data_off_t) - 1));
507 } 510 }
508 511
509 /* 512 /*
510 * Make a byte range in the data block unused. 513 * Make a byte range in the data block unused.
511 * Its current contents are unimportant. 514 * Its current contents are unimportant.
512 */ 515 */
513 void 516 void
514 xfs_dir2_data_make_free( 517 xfs_dir2_data_make_free(
515 xfs_trans_t *tp, /* transaction pointer */ 518 xfs_trans_t *tp, /* transaction pointer */
516 xfs_dabuf_t *bp, /* block buffer */ 519 xfs_dabuf_t *bp, /* block buffer */
517 xfs_dir2_data_aoff_t offset, /* starting byte offset */ 520 xfs_dir2_data_aoff_t offset, /* starting byte offset */
518 xfs_dir2_data_aoff_t len, /* length in bytes */ 521 xfs_dir2_data_aoff_t len, /* length in bytes */
519 int *needlogp, /* out: log header */ 522 int *needlogp, /* out: log header */
520 int *needscanp) /* out: regen bestfree */ 523 int *needscanp) /* out: regen bestfree */
521 { 524 {
522 xfs_dir2_data_t *d; /* data block pointer */ 525 xfs_dir2_data_t *d; /* data block pointer */
523 xfs_dir2_data_free_t *dfp; /* bestfree pointer */ 526 xfs_dir2_data_free_t *dfp; /* bestfree pointer */
524 char *endptr; /* end of data area */ 527 char *endptr; /* end of data area */
525 xfs_mount_t *mp; /* filesystem mount point */ 528 xfs_mount_t *mp; /* filesystem mount point */
526 int needscan; /* need to regen bestfree */ 529 int needscan; /* need to regen bestfree */
527 xfs_dir2_data_unused_t *newdup; /* new unused entry */ 530 xfs_dir2_data_unused_t *newdup; /* new unused entry */
528 xfs_dir2_data_unused_t *postdup; /* unused entry after us */ 531 xfs_dir2_data_unused_t *postdup; /* unused entry after us */
529 xfs_dir2_data_unused_t *prevdup; /* unused entry before us */ 532 xfs_dir2_data_unused_t *prevdup; /* unused entry before us */
530 533
531 mp = tp->t_mountp; 534 mp = tp->t_mountp;
532 d = bp->data; 535 d = bp->data;
533 /* 536 /*
534 * Figure out where the end of the data area is. 537 * Figure out where the end of the data area is.
535 */ 538 */
536 if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC) 539 if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC)
537 endptr = (char *)d + mp->m_dirblksize; 540 endptr = (char *)d + mp->m_dirblksize;
538 else { 541 else {
539 xfs_dir2_block_tail_t *btp; /* block tail */ 542 xfs_dir2_block_tail_t *btp; /* block tail */
540 543
541 ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); 544 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
542 btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d); 545 btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d);
543 endptr = (char *)XFS_DIR2_BLOCK_LEAF_P(btp); 546 endptr = (char *)XFS_DIR2_BLOCK_LEAF_P(btp);
544 } 547 }
545 /* 548 /*
546 * If this isn't the start of the block, then back up to 549 * If this isn't the start of the block, then back up to
547 * the previous entry and see if it's free. 550 * the previous entry and see if it's free.
548 */ 551 */
549 if (offset > sizeof(d->hdr)) { 552 if (offset > sizeof(d->hdr)) {
550 xfs_dir2_data_off_t *tagp; /* tag just before us */ 553 xfs_dir2_data_off_t *tagp; /* tag just before us */
551 554
552 tagp = (xfs_dir2_data_off_t *)((char *)d + offset) - 1; 555 tagp = (xfs_dir2_data_off_t *)((char *)d + offset) - 1;
553 prevdup = (xfs_dir2_data_unused_t *)((char *)d + INT_GET(*tagp, ARCH_CONVERT)); 556 prevdup = (xfs_dir2_data_unused_t *)((char *)d + INT_GET(*tagp, ARCH_CONVERT));
554 if (INT_GET(prevdup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG) 557 if (INT_GET(prevdup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG)
555 prevdup = NULL; 558 prevdup = NULL;
556 } else 559 } else
557 prevdup = NULL; 560 prevdup = NULL;
558 /* 561 /*
559 * If this isn't the end of the block, see if the entry after 562 * If this isn't the end of the block, see if the entry after
560 * us is free. 563 * us is free.
561 */ 564 */
562 if ((char *)d + offset + len < endptr) { 565 if ((char *)d + offset + len < endptr) {
563 postdup = 566 postdup =
564 (xfs_dir2_data_unused_t *)((char *)d + offset + len); 567 (xfs_dir2_data_unused_t *)((char *)d + offset + len);
565 if (INT_GET(postdup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG) 568 if (INT_GET(postdup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG)
566 postdup = NULL; 569 postdup = NULL;
567 } else 570 } else
568 postdup = NULL; 571 postdup = NULL;
569 ASSERT(*needscanp == 0); 572 ASSERT(*needscanp == 0);
570 needscan = 0; 573 needscan = 0;
571 /* 574 /*
572 * Previous and following entries are both free, 575 * Previous and following entries are both free,
573 * merge everything into a single free entry. 576 * merge everything into a single free entry.
574 */ 577 */
575 if (prevdup && postdup) { 578 if (prevdup && postdup) {
576 xfs_dir2_data_free_t *dfp2; /* another bestfree pointer */ 579 xfs_dir2_data_free_t *dfp2; /* another bestfree pointer */
577 580
578 /* 581 /*
579 * See if prevdup and/or postdup are in bestfree table. 582 * See if prevdup and/or postdup are in bestfree table.
580 */ 583 */
581 dfp = xfs_dir2_data_freefind(d, prevdup); 584 dfp = xfs_dir2_data_freefind(d, prevdup);
582 dfp2 = xfs_dir2_data_freefind(d, postdup); 585 dfp2 = xfs_dir2_data_freefind(d, postdup);
583 /* 586 /*
584 * We need a rescan unless there are exactly 2 free entries 587 * We need a rescan unless there are exactly 2 free entries
585 * namely our two. Then we know what's happening, otherwise 588 * namely our two. Then we know what's happening, otherwise
586 * since the third bestfree is there, there might be more 589 * since the third bestfree is there, there might be more
587 * entries. 590 * entries.
588 */ 591 */
589 needscan = d->hdr.bestfree[2].length; 592 needscan = (d->hdr.bestfree[2].length != 0);
590 /* 593 /*
591 * Fix up the new big freespace. 594 * Fix up the new big freespace.
592 */ 595 */
593 INT_MOD(prevdup->length, ARCH_CONVERT, len + INT_GET(postdup->length, ARCH_CONVERT)); 596 INT_MOD(prevdup->length, ARCH_CONVERT, len + INT_GET(postdup->length, ARCH_CONVERT));
594 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(prevdup), ARCH_CONVERT, 597 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(prevdup), ARCH_CONVERT,
595 (xfs_dir2_data_off_t)((char *)prevdup - (char *)d)); 598 (xfs_dir2_data_off_t)((char *)prevdup - (char *)d));
596 xfs_dir2_data_log_unused(tp, bp, prevdup); 599 xfs_dir2_data_log_unused(tp, bp, prevdup);
597 if (!needscan) { 600 if (!needscan) {
598 /* 601 /*
599 * Has to be the case that entries 0 and 1 are 602 * Has to be the case that entries 0 and 1 are
600 * dfp and dfp2 (don't know which is which), and 603 * dfp and dfp2 (don't know which is which), and
601 * entry 2 is empty. 604 * entry 2 is empty.
602 * Remove entry 1 first then entry 0. 605 * Remove entry 1 first then entry 0.
603 */ 606 */
604 ASSERT(dfp && dfp2); 607 ASSERT(dfp && dfp2);
605 if (dfp == &d->hdr.bestfree[1]) { 608 if (dfp == &d->hdr.bestfree[1]) {
606 dfp = &d->hdr.bestfree[0]; 609 dfp = &d->hdr.bestfree[0];
607 ASSERT(dfp2 == dfp); 610 ASSERT(dfp2 == dfp);
608 dfp2 = &d->hdr.bestfree[1]; 611 dfp2 = &d->hdr.bestfree[1];
609 } 612 }
610 xfs_dir2_data_freeremove(d, dfp2, needlogp); 613 xfs_dir2_data_freeremove(d, dfp2, needlogp);
611 xfs_dir2_data_freeremove(d, dfp, needlogp); 614 xfs_dir2_data_freeremove(d, dfp, needlogp);
612 /* 615 /*
613 * Now insert the new entry. 616 * Now insert the new entry.
614 */ 617 */
615 dfp = xfs_dir2_data_freeinsert(d, prevdup, needlogp); 618 dfp = xfs_dir2_data_freeinsert(d, prevdup, needlogp);
616 ASSERT(dfp == &d->hdr.bestfree[0]); 619 ASSERT(dfp == &d->hdr.bestfree[0]);
617 ASSERT(INT_GET(dfp->length, ARCH_CONVERT) == INT_GET(prevdup->length, ARCH_CONVERT)); 620 ASSERT(be16_to_cpu(dfp->length) == INT_GET(prevdup->length, ARCH_CONVERT));
618 ASSERT(!dfp[1].length); 621 ASSERT(!dfp[1].length);
619 ASSERT(!dfp[2].length); 622 ASSERT(!dfp[2].length);
620 } 623 }
621 } 624 }
622 /* 625 /*
623 * The entry before us is free, merge with it. 626 * The entry before us is free, merge with it.
624 */ 627 */
625 else if (prevdup) { 628 else if (prevdup) {
626 dfp = xfs_dir2_data_freefind(d, prevdup); 629 dfp = xfs_dir2_data_freefind(d, prevdup);
627 INT_MOD(prevdup->length, ARCH_CONVERT, len); 630 INT_MOD(prevdup->length, ARCH_CONVERT, len);
628 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(prevdup), ARCH_CONVERT, 631 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(prevdup), ARCH_CONVERT,
629 (xfs_dir2_data_off_t)((char *)prevdup - (char *)d)); 632 (xfs_dir2_data_off_t)((char *)prevdup - (char *)d));
630 xfs_dir2_data_log_unused(tp, bp, prevdup); 633 xfs_dir2_data_log_unused(tp, bp, prevdup);
631 /* 634 /*
632 * If the previous entry was in the table, the new entry 635 * If the previous entry was in the table, the new entry
633 * is longer, so it will be in the table too. Remove 636 * is longer, so it will be in the table too. Remove
634 * the old one and add the new one. 637 * the old one and add the new one.
635 */ 638 */
636 if (dfp) { 639 if (dfp) {
637 xfs_dir2_data_freeremove(d, dfp, needlogp); 640 xfs_dir2_data_freeremove(d, dfp, needlogp);
638 (void)xfs_dir2_data_freeinsert(d, prevdup, needlogp); 641 (void)xfs_dir2_data_freeinsert(d, prevdup, needlogp);
639 } 642 }
640 /* 643 /*
641 * Otherwise we need a scan if the new entry is big enough. 644 * Otherwise we need a scan if the new entry is big enough.
642 */ 645 */
643 else 646 else {
644 needscan = INT_GET(prevdup->length, ARCH_CONVERT) > INT_GET(d->hdr.bestfree[2].length, ARCH_CONVERT); 647 needscan = INT_GET(prevdup->length, ARCH_CONVERT) >
648 be16_to_cpu(d->hdr.bestfree[2].length);
649 }
645 } 650 }
646 /* 651 /*
647 * The following entry is free, merge with it. 652 * The following entry is free, merge with it.
648 */ 653 */
649 else if (postdup) { 654 else if (postdup) {
650 dfp = xfs_dir2_data_freefind(d, postdup); 655 dfp = xfs_dir2_data_freefind(d, postdup);
651 newdup = (xfs_dir2_data_unused_t *)((char *)d + offset); 656 newdup = (xfs_dir2_data_unused_t *)((char *)d + offset);
652 INT_SET(newdup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG); 657 INT_SET(newdup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG);
653 INT_SET(newdup->length, ARCH_CONVERT, len + INT_GET(postdup->length, ARCH_CONVERT)); 658 INT_SET(newdup->length, ARCH_CONVERT, len + INT_GET(postdup->length, ARCH_CONVERT));
654 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT, 659 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT,
655 (xfs_dir2_data_off_t)((char *)newdup - (char *)d)); 660 (xfs_dir2_data_off_t)((char *)newdup - (char *)d));
656 xfs_dir2_data_log_unused(tp, bp, newdup); 661 xfs_dir2_data_log_unused(tp, bp, newdup);
657 /* 662 /*
658 * If the following entry was in the table, the new entry 663 * If the following entry was in the table, the new entry
659 * is longer, so it will be in the table too. Remove 664 * is longer, so it will be in the table too. Remove
660 * the old one and add the new one. 665 * the old one and add the new one.
661 */ 666 */
662 if (dfp) { 667 if (dfp) {
663 xfs_dir2_data_freeremove(d, dfp, needlogp); 668 xfs_dir2_data_freeremove(d, dfp, needlogp);
664 (void)xfs_dir2_data_freeinsert(d, newdup, needlogp); 669 (void)xfs_dir2_data_freeinsert(d, newdup, needlogp);
665 } 670 }
666 /* 671 /*
667 * Otherwise we need a scan if the new entry is big enough. 672 * Otherwise we need a scan if the new entry is big enough.
668 */ 673 */
669 else 674 else {
670 needscan = INT_GET(newdup->length, ARCH_CONVERT) > INT_GET(d->hdr.bestfree[2].length, ARCH_CONVERT); 675 needscan = INT_GET(newdup->length, ARCH_CONVERT) >
676 be16_to_cpu(d->hdr.bestfree[2].length);
677 }
671 } 678 }
672 /* 679 /*
673 * Neither neighbor is free. Make a new entry. 680 * Neither neighbor is free. Make a new entry.
674 */ 681 */
675 else { 682 else {
676 newdup = (xfs_dir2_data_unused_t *)((char *)d + offset); 683 newdup = (xfs_dir2_data_unused_t *)((char *)d + offset);
677 INT_SET(newdup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG); 684 INT_SET(newdup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG);
678 INT_SET(newdup->length, ARCH_CONVERT, len); 685 INT_SET(newdup->length, ARCH_CONVERT, len);
679 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT, 686 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT,
680 (xfs_dir2_data_off_t)((char *)newdup - (char *)d)); 687 (xfs_dir2_data_off_t)((char *)newdup - (char *)d));
681 xfs_dir2_data_log_unused(tp, bp, newdup); 688 xfs_dir2_data_log_unused(tp, bp, newdup);
682 (void)xfs_dir2_data_freeinsert(d, newdup, needlogp); 689 (void)xfs_dir2_data_freeinsert(d, newdup, needlogp);
683 } 690 }
684 *needscanp = needscan; 691 *needscanp = needscan;
685 } 692 }
686 693
687 /* 694 /*
688 * Take a byte range out of an existing unused space and make it un-free. 695 * Take a byte range out of an existing unused space and make it un-free.
689 */ 696 */
690 void 697 void
691 xfs_dir2_data_use_free( 698 xfs_dir2_data_use_free(
692 xfs_trans_t *tp, /* transaction pointer */ 699 xfs_trans_t *tp, /* transaction pointer */
693 xfs_dabuf_t *bp, /* data block buffer */ 700 xfs_dabuf_t *bp, /* data block buffer */
694 xfs_dir2_data_unused_t *dup, /* unused entry */ 701 xfs_dir2_data_unused_t *dup, /* unused entry */
695 xfs_dir2_data_aoff_t offset, /* starting offset to use */ 702 xfs_dir2_data_aoff_t offset, /* starting offset to use */
696 xfs_dir2_data_aoff_t len, /* length to use */ 703 xfs_dir2_data_aoff_t len, /* length to use */
697 int *needlogp, /* out: need to log header */ 704 int *needlogp, /* out: need to log header */
698 int *needscanp) /* out: need regen bestfree */ 705 int *needscanp) /* out: need regen bestfree */
699 { 706 {
700 xfs_dir2_data_t *d; /* data block */ 707 xfs_dir2_data_t *d; /* data block */
701 xfs_dir2_data_free_t *dfp; /* bestfree pointer */ 708 xfs_dir2_data_free_t *dfp; /* bestfree pointer */
702 int matchback; /* matches end of freespace */ 709 int matchback; /* matches end of freespace */
703 int matchfront; /* matches start of freespace */ 710 int matchfront; /* matches start of freespace */
704 int needscan; /* need to regen bestfree */ 711 int needscan; /* need to regen bestfree */
705 xfs_dir2_data_unused_t *newdup; /* new unused entry */ 712 xfs_dir2_data_unused_t *newdup; /* new unused entry */
706 xfs_dir2_data_unused_t *newdup2; /* another new unused entry */ 713 xfs_dir2_data_unused_t *newdup2; /* another new unused entry */
707 int oldlen; /* old unused entry's length */ 714 int oldlen; /* old unused entry's length */
708 715
709 d = bp->data; 716 d = bp->data;
710 ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC || 717 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
711 INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC); 718 be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
712 ASSERT(INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG); 719 ASSERT(INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG);
713 ASSERT(offset >= (char *)dup - (char *)d); 720 ASSERT(offset >= (char *)dup - (char *)d);
714 ASSERT(offset + len <= (char *)dup + INT_GET(dup->length, ARCH_CONVERT) - (char *)d); 721 ASSERT(offset + len <= (char *)dup + INT_GET(dup->length, ARCH_CONVERT) - (char *)d);
715 ASSERT((char *)dup - (char *)d == INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT)); 722 ASSERT((char *)dup - (char *)d == INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT));
716 /* 723 /*
717 * Look up the entry in the bestfree table. 724 * Look up the entry in the bestfree table.
718 */ 725 */
719 dfp = xfs_dir2_data_freefind(d, dup); 726 dfp = xfs_dir2_data_freefind(d, dup);
720 oldlen = INT_GET(dup->length, ARCH_CONVERT); 727 oldlen = INT_GET(dup->length, ARCH_CONVERT);
721 ASSERT(dfp || oldlen <= INT_GET(d->hdr.bestfree[2].length, ARCH_CONVERT)); 728 ASSERT(dfp || oldlen <= be16_to_cpu(d->hdr.bestfree[2].length));
722 /* 729 /*
723 * Check for alignment with front and back of the entry. 730 * Check for alignment with front and back of the entry.
724 */ 731 */
725 matchfront = (char *)dup - (char *)d == offset; 732 matchfront = (char *)dup - (char *)d == offset;
726 matchback = (char *)dup + oldlen - (char *)d == offset + len; 733 matchback = (char *)dup + oldlen - (char *)d == offset + len;
727 ASSERT(*needscanp == 0); 734 ASSERT(*needscanp == 0);
728 needscan = 0; 735 needscan = 0;
729 /* 736 /*
730 * If we matched it exactly we just need to get rid of it from 737 * If we matched it exactly we just need to get rid of it from
731 * the bestfree table. 738 * the bestfree table.
732 */ 739 */
733 if (matchfront && matchback) { 740 if (matchfront && matchback) {
734 if (dfp) { 741 if (dfp) {
735 needscan = d->hdr.bestfree[2].offset; 742 needscan = (d->hdr.bestfree[2].offset != 0);
736 if (!needscan) 743 if (!needscan)
737 xfs_dir2_data_freeremove(d, dfp, needlogp); 744 xfs_dir2_data_freeremove(d, dfp, needlogp);
738 } 745 }
739 } 746 }
740 /* 747 /*
741 * We match the first part of the entry. 748 * We match the first part of the entry.
742 * Make a new entry with the remaining freespace. 749 * Make a new entry with the remaining freespace.
743 */ 750 */
744 else if (matchfront) { 751 else if (matchfront) {
745 newdup = (xfs_dir2_data_unused_t *)((char *)d + offset + len); 752 newdup = (xfs_dir2_data_unused_t *)((char *)d + offset + len);
746 INT_SET(newdup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG); 753 INT_SET(newdup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG);
747 INT_SET(newdup->length, ARCH_CONVERT, oldlen - len); 754 INT_SET(newdup->length, ARCH_CONVERT, oldlen - len);
748 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT, 755 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT,
749 (xfs_dir2_data_off_t)((char *)newdup - (char *)d)); 756 (xfs_dir2_data_off_t)((char *)newdup - (char *)d));
750 xfs_dir2_data_log_unused(tp, bp, newdup); 757 xfs_dir2_data_log_unused(tp, bp, newdup);
751 /* 758 /*
752 * If it was in the table, remove it and add the new one. 759 * If it was in the table, remove it and add the new one.
753 */ 760 */
754 if (dfp) { 761 if (dfp) {
755 xfs_dir2_data_freeremove(d, dfp, needlogp); 762 xfs_dir2_data_freeremove(d, dfp, needlogp);
756 dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp); 763 dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp);
757 ASSERT(dfp != NULL); 764 ASSERT(dfp != NULL);
758 ASSERT(INT_GET(dfp->length, ARCH_CONVERT) == INT_GET(newdup->length, ARCH_CONVERT)); 765 ASSERT(be16_to_cpu(dfp->length) == INT_GET(newdup->length, ARCH_CONVERT));
759 ASSERT(INT_GET(dfp->offset, ARCH_CONVERT) == (char *)newdup - (char *)d); 766 ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)d);
760 /* 767 /*
761 * If we got inserted at the last slot, 768 * If we got inserted at the last slot,
762 * that means we don't know if there was a better 769 * that means we don't know if there was a better
763 * choice for the last slot, or not. Rescan. 770 * choice for the last slot, or not. Rescan.
764 */ 771 */
765 needscan = dfp == &d->hdr.bestfree[2]; 772 needscan = dfp == &d->hdr.bestfree[2];
766 } 773 }
767 } 774 }
768 /* 775 /*
769 * We match the last part of the entry. 776 * We match the last part of the entry.
770 * Trim the allocated space off the tail of the entry. 777 * Trim the allocated space off the tail of the entry.
771 */ 778 */
772 else if (matchback) { 779 else if (matchback) {
773 newdup = dup; 780 newdup = dup;
774 INT_SET(newdup->length, ARCH_CONVERT, (xfs_dir2_data_off_t) 781 INT_SET(newdup->length, ARCH_CONVERT, (xfs_dir2_data_off_t)
775 (((char *)d + offset) - (char *)newdup)); 782 (((char *)d + offset) - (char *)newdup));
776 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT, 783 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT,
777 (xfs_dir2_data_off_t)((char *)newdup - (char *)d)); 784 (xfs_dir2_data_off_t)((char *)newdup - (char *)d));
778 xfs_dir2_data_log_unused(tp, bp, newdup); 785 xfs_dir2_data_log_unused(tp, bp, newdup);
779 /* 786 /*
780 * If it was in the table, remove it and add the new one. 787 * If it was in the table, remove it and add the new one.
781 */ 788 */
782 if (dfp) { 789 if (dfp) {
783 xfs_dir2_data_freeremove(d, dfp, needlogp); 790 xfs_dir2_data_freeremove(d, dfp, needlogp);
784 dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp); 791 dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp);
785 ASSERT(dfp != NULL); 792 ASSERT(dfp != NULL);
786 ASSERT(INT_GET(dfp->length, ARCH_CONVERT) == INT_GET(newdup->length, ARCH_CONVERT)); 793 ASSERT(be16_to_cpu(dfp->length) == INT_GET(newdup->length, ARCH_CONVERT));
787 ASSERT(INT_GET(dfp->offset, ARCH_CONVERT) == (char *)newdup - (char *)d); 794 ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)d);
788 /* 795 /*
789 * If we got inserted at the last slot, 796 * If we got inserted at the last slot,
790 * that means we don't know if there was a better 797 * that means we don't know if there was a better
791 * choice for the last slot, or not. Rescan. 798 * choice for the last slot, or not. Rescan.
792 */ 799 */
793 needscan = dfp == &d->hdr.bestfree[2]; 800 needscan = dfp == &d->hdr.bestfree[2];
794 } 801 }
795 } 802 }
796 /* 803 /*
797 * Poking out the middle of an entry. 804 * Poking out the middle of an entry.
798 * Make two new entries. 805 * Make two new entries.
799 */ 806 */
800 else { 807 else {
801 newdup = dup; 808 newdup = dup;
802 INT_SET(newdup->length, ARCH_CONVERT, (xfs_dir2_data_off_t) 809 INT_SET(newdup->length, ARCH_CONVERT, (xfs_dir2_data_off_t)
803 (((char *)d + offset) - (char *)newdup)); 810 (((char *)d + offset) - (char *)newdup));
804 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT, 811 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT,
805 (xfs_dir2_data_off_t)((char *)newdup - (char *)d)); 812 (xfs_dir2_data_off_t)((char *)newdup - (char *)d));
806 xfs_dir2_data_log_unused(tp, bp, newdup); 813 xfs_dir2_data_log_unused(tp, bp, newdup);
807 newdup2 = (xfs_dir2_data_unused_t *)((char *)d + offset + len); 814 newdup2 = (xfs_dir2_data_unused_t *)((char *)d + offset + len);
808 INT_SET(newdup2->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG); 815 INT_SET(newdup2->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG);
809 INT_SET(newdup2->length, ARCH_CONVERT, oldlen - len - INT_GET(newdup->length, ARCH_CONVERT)); 816 INT_SET(newdup2->length, ARCH_CONVERT, oldlen - len - INT_GET(newdup->length, ARCH_CONVERT));
810 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup2), ARCH_CONVERT, 817 INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup2), ARCH_CONVERT,
811 (xfs_dir2_data_off_t)((char *)newdup2 - (char *)d)); 818 (xfs_dir2_data_off_t)((char *)newdup2 - (char *)d));
812 xfs_dir2_data_log_unused(tp, bp, newdup2); 819 xfs_dir2_data_log_unused(tp, bp, newdup2);
813 /* 820 /*
814 * If the old entry was in the table, we need to scan 821 * If the old entry was in the table, we need to scan
815 * if the 3rd entry was valid, since these entries 822 * if the 3rd entry was valid, since these entries
816 * are smaller than the old one. 823 * are smaller than the old one.
817 * If we don't need to scan that means there were 1 or 2 824 * If we don't need to scan that means there were 1 or 2
818 * entries in the table, and removing the old and adding 825 * entries in the table, and removing the old and adding
819 * the 2 new will work. 826 * the 2 new will work.
820 */ 827 */
821 if (dfp) { 828 if (dfp) {
822 needscan = d->hdr.bestfree[2].length; 829 needscan = (d->hdr.bestfree[2].length != 0);
823 if (!needscan) { 830 if (!needscan) {
824 xfs_dir2_data_freeremove(d, dfp, needlogp); 831 xfs_dir2_data_freeremove(d, dfp, needlogp);
825 (void)xfs_dir2_data_freeinsert(d, newdup, 832 (void)xfs_dir2_data_freeinsert(d, newdup,
826 needlogp); 833 needlogp);
827 (void)xfs_dir2_data_freeinsert(d, newdup2, 834 (void)xfs_dir2_data_freeinsert(d, newdup2,
828 needlogp); 835 needlogp);
829 } 836 }
830 } 837 }
831 } 838 }
832 *needscanp = needscan; 839 *needscanp = needscan;
833 } 840 }
834 841
fs/xfs/xfs_dir2_data.h
1 /* 1 /*
2 * Copyright (c) 2000,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000,2005 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 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 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 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, 15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18 #ifndef __XFS_DIR2_DATA_H__ 18 #ifndef __XFS_DIR2_DATA_H__
19 #define __XFS_DIR2_DATA_H__ 19 #define __XFS_DIR2_DATA_H__
20 20
21 /* 21 /*
22 * Directory format 2, data block structures. 22 * Directory format 2, data block structures.
23 */ 23 */
24 24
25 struct xfs_dabuf; 25 struct xfs_dabuf;
26 struct xfs_da_args; 26 struct xfs_da_args;
27 struct xfs_inode; 27 struct xfs_inode;
28 struct xfs_trans; 28 struct xfs_trans;
29 29
30 /* 30 /*
31 * Constants. 31 * Constants.
32 */ 32 */
33 #define XFS_DIR2_DATA_MAGIC 0x58443244 /* XD2D: for multiblock dirs */ 33 #define XFS_DIR2_DATA_MAGIC 0x58443244 /* XD2D: for multiblock dirs */
34 #define XFS_DIR2_DATA_ALIGN_LOG 3 /* i.e., 8 bytes */ 34 #define XFS_DIR2_DATA_ALIGN_LOG 3 /* i.e., 8 bytes */
35 #define XFS_DIR2_DATA_ALIGN (1 << XFS_DIR2_DATA_ALIGN_LOG) 35 #define XFS_DIR2_DATA_ALIGN (1 << XFS_DIR2_DATA_ALIGN_LOG)
36 #define XFS_DIR2_DATA_FREE_TAG 0xffff 36 #define XFS_DIR2_DATA_FREE_TAG 0xffff
37 #define XFS_DIR2_DATA_FD_COUNT 3 37 #define XFS_DIR2_DATA_FD_COUNT 3
38 38
39 /* 39 /*
40 * Directory address space divided into sections, 40 * Directory address space divided into sections,
41 * spaces separated by 32gb. 41 * spaces separated by 32gb.
42 */ 42 */
43 #define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG)) 43 #define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG))
44 #define XFS_DIR2_DATA_SPACE 0 44 #define XFS_DIR2_DATA_SPACE 0
45 #define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE) 45 #define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE)
46 #define XFS_DIR2_DATA_FIRSTDB(mp) \ 46 #define XFS_DIR2_DATA_FIRSTDB(mp) \
47 XFS_DIR2_BYTE_TO_DB(mp, XFS_DIR2_DATA_OFFSET) 47 XFS_DIR2_BYTE_TO_DB(mp, XFS_DIR2_DATA_OFFSET)
48 48
49 /* 49 /*
50 * Offsets of . and .. in data space (always block 0) 50 * Offsets of . and .. in data space (always block 0)
51 */ 51 */
52 #define XFS_DIR2_DATA_DOT_OFFSET \ 52 #define XFS_DIR2_DATA_DOT_OFFSET \
53 ((xfs_dir2_data_aoff_t)sizeof(xfs_dir2_data_hdr_t)) 53 ((xfs_dir2_data_aoff_t)sizeof(xfs_dir2_data_hdr_t))
54 #define XFS_DIR2_DATA_DOTDOT_OFFSET \ 54 #define XFS_DIR2_DATA_DOTDOT_OFFSET \
55 (XFS_DIR2_DATA_DOT_OFFSET + XFS_DIR2_DATA_ENTSIZE(1)) 55 (XFS_DIR2_DATA_DOT_OFFSET + XFS_DIR2_DATA_ENTSIZE(1))
56 #define XFS_DIR2_DATA_FIRST_OFFSET \ 56 #define XFS_DIR2_DATA_FIRST_OFFSET \
57 (XFS_DIR2_DATA_DOTDOT_OFFSET + XFS_DIR2_DATA_ENTSIZE(2)) 57 (XFS_DIR2_DATA_DOTDOT_OFFSET + XFS_DIR2_DATA_ENTSIZE(2))
58 58
59 /* 59 /*
60 * Structures. 60 * Structures.
61 */ 61 */
62 62
63 /* 63 /*
64 * Describe a free area in the data block. 64 * Describe a free area in the data block.
65 * The freespace will be formatted as a xfs_dir2_data_unused_t. 65 * The freespace will be formatted as a xfs_dir2_data_unused_t.
66 */ 66 */
67 typedef struct xfs_dir2_data_free { 67 typedef struct xfs_dir2_data_free {
68 xfs_dir2_data_off_t offset; /* start of freespace */ 68 __be16 offset; /* start of freespace */
69 xfs_dir2_data_off_t length; /* length of freespace */ 69 __be16 length; /* length of freespace */
70 } xfs_dir2_data_free_t; 70 } xfs_dir2_data_free_t;
71 71
72 /* 72 /*
73 * Header for the data blocks. 73 * Header for the data blocks.
74 * Always at the beginning of a directory-sized block. 74 * Always at the beginning of a directory-sized block.
75 * The code knows that XFS_DIR2_DATA_FD_COUNT is 3. 75 * The code knows that XFS_DIR2_DATA_FD_COUNT is 3.
76 */ 76 */
77 typedef struct xfs_dir2_data_hdr { 77 typedef struct xfs_dir2_data_hdr {
78 __uint32_t magic; /* XFS_DIR2_DATA_MAGIC */ 78 __be32 magic; /* XFS_DIR2_DATA_MAGIC */
79 /* or XFS_DIR2_BLOCK_MAGIC */ 79 /* or XFS_DIR2_BLOCK_MAGIC */
80 xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT]; 80 xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT];
81 } xfs_dir2_data_hdr_t; 81 } xfs_dir2_data_hdr_t;
82 82
83 /* 83 /*
84 * Active entry in a data block. Aligned to 8 bytes. 84 * Active entry in a data block. Aligned to 8 bytes.
85 * Tag appears as the last 2 bytes. 85 * Tag appears as the last 2 bytes.
86 */ 86 */
87 typedef struct xfs_dir2_data_entry { 87 typedef struct xfs_dir2_data_entry {
88 xfs_ino_t inumber; /* inode number */ 88 xfs_ino_t inumber; /* inode number */
89 __uint8_t namelen; /* name length */ 89 __uint8_t namelen; /* name length */
90 __uint8_t name[1]; /* name bytes, no null */ 90 __uint8_t name[1]; /* name bytes, no null */
91 /* variable offset */ 91 /* variable offset */
92 xfs_dir2_data_off_t tag; /* starting offset of us */ 92 xfs_dir2_data_off_t tag; /* starting offset of us */
93 } xfs_dir2_data_entry_t; 93 } xfs_dir2_data_entry_t;
94 94
95 /* 95 /*
96 * Unused entry in a data block. Aligned to 8 bytes. 96 * Unused entry in a data block. Aligned to 8 bytes.
97 * Tag appears as the last 2 bytes. 97 * Tag appears as the last 2 bytes.
98 */ 98 */
99 typedef struct xfs_dir2_data_unused { 99 typedef struct xfs_dir2_data_unused {
100 __uint16_t freetag; /* XFS_DIR2_DATA_FREE_TAG */ 100 __uint16_t freetag; /* XFS_DIR2_DATA_FREE_TAG */
101 xfs_dir2_data_off_t length; /* total free length */ 101 xfs_dir2_data_off_t length; /* total free length */
102 /* variable offset */ 102 /* variable offset */
103 xfs_dir2_data_off_t tag; /* starting offset of us */ 103 xfs_dir2_data_off_t tag; /* starting offset of us */
104 } xfs_dir2_data_unused_t; 104 } xfs_dir2_data_unused_t;
105 105
106 typedef union { 106 typedef union {
107 xfs_dir2_data_entry_t entry; 107 xfs_dir2_data_entry_t entry;
108 xfs_dir2_data_unused_t unused; 108 xfs_dir2_data_unused_t unused;
109 } xfs_dir2_data_union_t; 109 } xfs_dir2_data_union_t;
110 110
111 /* 111 /*
112 * Generic data block structure, for xfs_db. 112 * Generic data block structure, for xfs_db.
113 */ 113 */
114 typedef struct xfs_dir2_data { 114 typedef struct xfs_dir2_data {
115 xfs_dir2_data_hdr_t hdr; /* magic XFS_DIR2_DATA_MAGIC */ 115 xfs_dir2_data_hdr_t hdr; /* magic XFS_DIR2_DATA_MAGIC */
116 xfs_dir2_data_union_t u[1]; 116 xfs_dir2_data_union_t u[1];
117 } xfs_dir2_data_t; 117 } xfs_dir2_data_t;
118 118
119 /* 119 /*
120 * Macros. 120 * Macros.
121 */ 121 */
122 122
123 /* 123 /*
124 * Size of a data entry. 124 * Size of a data entry.
125 */ 125 */
126 #define XFS_DIR2_DATA_ENTSIZE(n) xfs_dir2_data_entsize(n) 126 #define XFS_DIR2_DATA_ENTSIZE(n) xfs_dir2_data_entsize(n)
127 static inline int xfs_dir2_data_entsize(int n) 127 static inline int xfs_dir2_data_entsize(int n)
128 { 128 {
129 return (int)roundup(offsetof(xfs_dir2_data_entry_t, name[0]) + (n) + \ 129 return (int)roundup(offsetof(xfs_dir2_data_entry_t, name[0]) + (n) + \
130 (uint)sizeof(xfs_dir2_data_off_t), XFS_DIR2_DATA_ALIGN); 130 (uint)sizeof(xfs_dir2_data_off_t), XFS_DIR2_DATA_ALIGN);
131 } 131 }
132 132
133 /* 133 /*
134 * Pointer to an entry's tag word. 134 * Pointer to an entry's tag word.
135 */ 135 */
136 #define XFS_DIR2_DATA_ENTRY_TAG_P(dep) xfs_dir2_data_entry_tag_p(dep) 136 #define XFS_DIR2_DATA_ENTRY_TAG_P(dep) xfs_dir2_data_entry_tag_p(dep)
137 static inline xfs_dir2_data_off_t * 137 static inline xfs_dir2_data_off_t *
138 xfs_dir2_data_entry_tag_p(xfs_dir2_data_entry_t *dep) 138 xfs_dir2_data_entry_tag_p(xfs_dir2_data_entry_t *dep)
139 { 139 {
140 return (xfs_dir2_data_off_t *) \ 140 return (xfs_dir2_data_off_t *) \
141 ((char *)(dep) + XFS_DIR2_DATA_ENTSIZE((dep)->namelen) - \ 141 ((char *)(dep) + XFS_DIR2_DATA_ENTSIZE((dep)->namelen) - \
142 (uint)sizeof(xfs_dir2_data_off_t)); 142 (uint)sizeof(xfs_dir2_data_off_t));
143 } 143 }
144 144
145 /* 145 /*
146 * Pointer to a freespace's tag word. 146 * Pointer to a freespace's tag word.
147 */ 147 */
148 #define XFS_DIR2_DATA_UNUSED_TAG_P(dup) \ 148 #define XFS_DIR2_DATA_UNUSED_TAG_P(dup) \
149 xfs_dir2_data_unused_tag_p(dup) 149 xfs_dir2_data_unused_tag_p(dup)
150 static inline xfs_dir2_data_off_t * 150 static inline xfs_dir2_data_off_t *
151 xfs_dir2_data_unused_tag_p(xfs_dir2_data_unused_t *dup) 151 xfs_dir2_data_unused_tag_p(xfs_dir2_data_unused_t *dup)
152 { 152 {
153 return (xfs_dir2_data_off_t *) \ 153 return (xfs_dir2_data_off_t *) \
154 ((char *)(dup) + INT_GET((dup)->length, ARCH_CONVERT) \ 154 ((char *)(dup) + INT_GET((dup)->length, ARCH_CONVERT) \
155 - (uint)sizeof(xfs_dir2_data_off_t)); 155 - (uint)sizeof(xfs_dir2_data_off_t));
156 } 156 }
157 157
158 /* 158 /*
159 * Function declarations. 159 * Function declarations.
160 */ 160 */
161 #ifdef DEBUG 161 #ifdef DEBUG
162 extern void xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_dabuf *bp); 162 extern void xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_dabuf *bp);
163 #else 163 #else
164 #define xfs_dir2_data_check(dp,bp) 164 #define xfs_dir2_data_check(dp,bp)
165 #endif 165 #endif
166 extern xfs_dir2_data_free_t *xfs_dir2_data_freefind(xfs_dir2_data_t *d, 166 extern xfs_dir2_data_free_t *xfs_dir2_data_freefind(xfs_dir2_data_t *d,
167 xfs_dir2_data_unused_t *dup); 167 xfs_dir2_data_unused_t *dup);
168 extern xfs_dir2_data_free_t *xfs_dir2_data_freeinsert(xfs_dir2_data_t *d, 168 extern xfs_dir2_data_free_t *xfs_dir2_data_freeinsert(xfs_dir2_data_t *d,
169 xfs_dir2_data_unused_t *dup, int *loghead); 169 xfs_dir2_data_unused_t *dup, int *loghead);
170 extern void xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d, 170 extern void xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d,
171 int *loghead, char *aendp); 171 int *loghead, char *aendp);
172 extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno, 172 extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno,
173 struct xfs_dabuf **bpp); 173 struct xfs_dabuf **bpp);
174 extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp, 174 extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp,
175 xfs_dir2_data_entry_t *dep); 175 xfs_dir2_data_entry_t *dep);
176 extern void xfs_dir2_data_log_header(struct xfs_trans *tp, 176 extern void xfs_dir2_data_log_header(struct xfs_trans *tp,
177 struct xfs_dabuf *bp); 177 struct xfs_dabuf *bp);
178 extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_dabuf *bp, 178 extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_dabuf *bp,
179 xfs_dir2_data_unused_t *dup); 179 xfs_dir2_data_unused_t *dup);
180 extern void xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_dabuf *bp, 180 extern void xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_dabuf *bp,
181 xfs_dir2_data_aoff_t offset, 181 xfs_dir2_data_aoff_t offset,
182 xfs_dir2_data_aoff_t len, int *needlogp, 182 xfs_dir2_data_aoff_t len, int *needlogp,
183 int *needscanp); 183 int *needscanp);
184 extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_dabuf *bp, 184 extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_dabuf *bp,
185 xfs_dir2_data_unused_t *dup, 185 xfs_dir2_data_unused_t *dup,
186 xfs_dir2_data_aoff_t offset, 186 xfs_dir2_data_aoff_t offset,
187 xfs_dir2_data_aoff_t len, int *needlogp, 187 xfs_dir2_data_aoff_t len, int *needlogp,
188 int *needscanp); 188 int *needscanp);
189 189
190 #endif /* __XFS_DIR2_DATA_H__ */ 190 #endif /* __XFS_DIR2_DATA_H__ */
191 191
fs/xfs/xfs_dir2_leaf.c
1 /* 1 /*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 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 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 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, 15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18 #include "xfs.h" 18 #include "xfs.h"
19 #include "xfs_fs.h" 19 #include "xfs_fs.h"
20 #include "xfs_types.h" 20 #include "xfs_types.h"
21 #include "xfs_bit.h" 21 #include "xfs_bit.h"
22 #include "xfs_log.h" 22 #include "xfs_log.h"
23 #include "xfs_inum.h" 23 #include "xfs_inum.h"
24 #include "xfs_trans.h" 24 #include "xfs_trans.h"
25 #include "xfs_sb.h" 25 #include "xfs_sb.h"
26 #include "xfs_ag.h" 26 #include "xfs_ag.h"
27 #include "xfs_dir.h" 27 #include "xfs_dir.h"
28 #include "xfs_dir2.h" 28 #include "xfs_dir2.h"
29 #include "xfs_dmapi.h" 29 #include "xfs_dmapi.h"
30 #include "xfs_mount.h" 30 #include "xfs_mount.h"
31 #include "xfs_da_btree.h" 31 #include "xfs_da_btree.h"
32 #include "xfs_bmap_btree.h" 32 #include "xfs_bmap_btree.h"
33 #include "xfs_attr_sf.h" 33 #include "xfs_attr_sf.h"
34 #include "xfs_dir_sf.h" 34 #include "xfs_dir_sf.h"
35 #include "xfs_dir2_sf.h" 35 #include "xfs_dir2_sf.h"
36 #include "xfs_dinode.h" 36 #include "xfs_dinode.h"
37 #include "xfs_inode.h" 37 #include "xfs_inode.h"
38 #include "xfs_bmap.h" 38 #include "xfs_bmap.h"
39 #include "xfs_dir2_data.h" 39 #include "xfs_dir2_data.h"
40 #include "xfs_dir2_leaf.h" 40 #include "xfs_dir2_leaf.h"
41 #include "xfs_dir2_block.h" 41 #include "xfs_dir2_block.h"
42 #include "xfs_dir2_node.h" 42 #include "xfs_dir2_node.h"
43 #include "xfs_dir2_trace.h" 43 #include "xfs_dir2_trace.h"
44 #include "xfs_error.h" 44 #include "xfs_error.h"
45 45
46 /* 46 /*
47 * Local function declarations. 47 * Local function declarations.
48 */ 48 */
49 #ifdef DEBUG 49 #ifdef DEBUG
50 static void xfs_dir2_leaf_check(xfs_inode_t *dp, xfs_dabuf_t *bp); 50 static void xfs_dir2_leaf_check(xfs_inode_t *dp, xfs_dabuf_t *bp);
51 #else 51 #else
52 #define xfs_dir2_leaf_check(dp, bp) 52 #define xfs_dir2_leaf_check(dp, bp)
53 #endif 53 #endif
54 static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **lbpp, 54 static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **lbpp,
55 int *indexp, xfs_dabuf_t **dbpp); 55 int *indexp, xfs_dabuf_t **dbpp);
56 static void xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp, 56 static void xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp,
57 int first, int last); 57 int first, int last);
58 static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp); 58 static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp);
59 59
60 60
61 /* 61 /*
62 * Convert a block form directory to a leaf form directory. 62 * Convert a block form directory to a leaf form directory.
63 */ 63 */
64 int /* error */ 64 int /* error */
65 xfs_dir2_block_to_leaf( 65 xfs_dir2_block_to_leaf(
66 xfs_da_args_t *args, /* operation arguments */ 66 xfs_da_args_t *args, /* operation arguments */
67 xfs_dabuf_t *dbp) /* input block's buffer */ 67 xfs_dabuf_t *dbp) /* input block's buffer */
68 { 68 {
69 xfs_dir2_data_off_t *bestsp; /* leaf's bestsp entries */ 69 xfs_dir2_data_off_t *bestsp; /* leaf's bestsp entries */
70 xfs_dablk_t blkno; /* leaf block's bno */ 70 xfs_dablk_t blkno; /* leaf block's bno */
71 xfs_dir2_block_t *block; /* block structure */ 71 xfs_dir2_block_t *block; /* block structure */
72 xfs_dir2_leaf_entry_t *blp; /* block's leaf entries */ 72 xfs_dir2_leaf_entry_t *blp; /* block's leaf entries */
73 xfs_dir2_block_tail_t *btp; /* block's tail */ 73 xfs_dir2_block_tail_t *btp; /* block's tail */
74 xfs_inode_t *dp; /* incore directory inode */ 74 xfs_inode_t *dp; /* incore directory inode */
75 int error; /* error return code */ 75 int error; /* error return code */
76 xfs_dabuf_t *lbp; /* leaf block's buffer */ 76 xfs_dabuf_t *lbp; /* leaf block's buffer */
77 xfs_dir2_db_t ldb; /* leaf block's bno */ 77 xfs_dir2_db_t ldb; /* leaf block's bno */
78 xfs_dir2_leaf_t *leaf; /* leaf structure */ 78 xfs_dir2_leaf_t *leaf; /* leaf structure */
79 xfs_dir2_leaf_tail_t *ltp; /* leaf's tail */ 79 xfs_dir2_leaf_tail_t *ltp; /* leaf's tail */
80 xfs_mount_t *mp; /* filesystem mount point */ 80 xfs_mount_t *mp; /* filesystem mount point */
81 int needlog; /* need to log block header */ 81 int needlog; /* need to log block header */
82 int needscan; /* need to rescan bestfree */ 82 int needscan; /* need to rescan bestfree */
83 xfs_trans_t *tp; /* transaction pointer */ 83 xfs_trans_t *tp; /* transaction pointer */
84 84
85 xfs_dir2_trace_args_b("block_to_leaf", args, dbp); 85 xfs_dir2_trace_args_b("block_to_leaf", args, dbp);
86 dp = args->dp; 86 dp = args->dp;
87 mp = dp->i_mount; 87 mp = dp->i_mount;
88 tp = args->trans; 88 tp = args->trans;
89 /* 89 /*
90 * Add the leaf block to the inode. 90 * Add the leaf block to the inode.
91 * This interface will only put blocks in the leaf/node range. 91 * This interface will only put blocks in the leaf/node range.
92 * Since that's empty now, we'll get the root (block 0 in range). 92 * Since that's empty now, we'll get the root (block 0 in range).
93 */ 93 */
94 if ((error = xfs_da_grow_inode(args, &blkno))) { 94 if ((error = xfs_da_grow_inode(args, &blkno))) {
95 return error; 95 return error;
96 } 96 }
97 ldb = XFS_DIR2_DA_TO_DB(mp, blkno); 97 ldb = XFS_DIR2_DA_TO_DB(mp, blkno);
98 ASSERT(ldb == XFS_DIR2_LEAF_FIRSTDB(mp)); 98 ASSERT(ldb == XFS_DIR2_LEAF_FIRSTDB(mp));
99 /* 99 /*
100 * Initialize the leaf block, get a buffer for it. 100 * Initialize the leaf block, get a buffer for it.
101 */ 101 */
102 if ((error = xfs_dir2_leaf_init(args, ldb, &lbp, XFS_DIR2_LEAF1_MAGIC))) { 102 if ((error = xfs_dir2_leaf_init(args, ldb, &lbp, XFS_DIR2_LEAF1_MAGIC))) {
103 return error; 103 return error;
104 } 104 }
105 ASSERT(lbp != NULL); 105 ASSERT(lbp != NULL);
106 leaf = lbp->data; 106 leaf = lbp->data;
107 block = dbp->data; 107 block = dbp->data;
108 xfs_dir2_data_check(dp, dbp); 108 xfs_dir2_data_check(dp, dbp);
109 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); 109 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
110 blp = XFS_DIR2_BLOCK_LEAF_P(btp); 110 blp = XFS_DIR2_BLOCK_LEAF_P(btp);
111 /* 111 /*
112 * Set the counts in the leaf header. 112 * Set the counts in the leaf header.
113 */ 113 */
114 INT_COPY(leaf->hdr.count, btp->count, ARCH_CONVERT); /* INT_: type change */ 114 INT_COPY(leaf->hdr.count, btp->count, ARCH_CONVERT); /* INT_: type change */
115 INT_COPY(leaf->hdr.stale, btp->stale, ARCH_CONVERT); /* INT_: type change */ 115 INT_COPY(leaf->hdr.stale, btp->stale, ARCH_CONVERT); /* INT_: type change */
116 /* 116 /*
117 * Could compact these but I think we always do the conversion 117 * Could compact these but I think we always do the conversion
118 * after squeezing out stale entries. 118 * after squeezing out stale entries.
119 */ 119 */
120 memcpy(leaf->ents, blp, INT_GET(btp->count, ARCH_CONVERT) * sizeof(xfs_dir2_leaf_entry_t)); 120 memcpy(leaf->ents, blp, INT_GET(btp->count, ARCH_CONVERT) * sizeof(xfs_dir2_leaf_entry_t));
121 xfs_dir2_leaf_log_ents(tp, lbp, 0, INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1); 121 xfs_dir2_leaf_log_ents(tp, lbp, 0, INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1);
122 needscan = 0; 122 needscan = 0;
123 needlog = 1; 123 needlog = 1;
124 /* 124 /*
125 * Make the space formerly occupied by the leaf entries and block 125 * Make the space formerly occupied by the leaf entries and block
126 * tail be free. 126 * tail be free.
127 */ 127 */
128 xfs_dir2_data_make_free(tp, dbp, 128 xfs_dir2_data_make_free(tp, dbp,
129 (xfs_dir2_data_aoff_t)((char *)blp - (char *)block), 129 (xfs_dir2_data_aoff_t)((char *)blp - (char *)block),
130 (xfs_dir2_data_aoff_t)((char *)block + mp->m_dirblksize - 130 (xfs_dir2_data_aoff_t)((char *)block + mp->m_dirblksize -
131 (char *)blp), 131 (char *)blp),
132 &needlog, &needscan); 132 &needlog, &needscan);
133 /* 133 /*
134 * Fix up the block header, make it a data block. 134 * Fix up the block header, make it a data block.
135 */ 135 */
136 INT_SET(block->hdr.magic, ARCH_CONVERT, XFS_DIR2_DATA_MAGIC); 136 block->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
137 if (needscan) 137 if (needscan)
138 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog, 138 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog,
139 NULL); 139 NULL);
140 /* 140 /*
141 * Set up leaf tail and bests table. 141 * Set up leaf tail and bests table.
142 */ 142 */
143 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); 143 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
144 INT_SET(ltp->bestcount, ARCH_CONVERT, 1); 144 INT_SET(ltp->bestcount, ARCH_CONVERT, 1);
145 bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); 145 bestsp = XFS_DIR2_LEAF_BESTS_P(ltp);
146 INT_COPY(bestsp[0], block->hdr.bestfree[0].length, ARCH_CONVERT); 146 bestsp[0] = block->hdr.bestfree[0].length;
147 /* 147 /*
148 * Log the data header and leaf bests table. 148 * Log the data header and leaf bests table.
149 */ 149 */
150 if (needlog) 150 if (needlog)
151 xfs_dir2_data_log_header(tp, dbp); 151 xfs_dir2_data_log_header(tp, dbp);
152 xfs_dir2_leaf_check(dp, lbp); 152 xfs_dir2_leaf_check(dp, lbp);
153 xfs_dir2_data_check(dp, dbp); 153 xfs_dir2_data_check(dp, dbp);
154 xfs_dir2_leaf_log_bests(tp, lbp, 0, 0); 154 xfs_dir2_leaf_log_bests(tp, lbp, 0, 0);
155 xfs_da_buf_done(lbp); 155 xfs_da_buf_done(lbp);
156 return 0; 156 return 0;
157 } 157 }
158 158
159 /* 159 /*
160 * Add an entry to a leaf form directory. 160 * Add an entry to a leaf form directory.
161 */ 161 */
162 int /* error */ 162 int /* error */
163 xfs_dir2_leaf_addname( 163 xfs_dir2_leaf_addname(
164 xfs_da_args_t *args) /* operation arguments */ 164 xfs_da_args_t *args) /* operation arguments */
165 { 165 {
166 xfs_dir2_data_off_t *bestsp; /* freespace table in leaf */ 166 xfs_dir2_data_off_t *bestsp; /* freespace table in leaf */
167 int compact; /* need to compact leaves */ 167 int compact; /* need to compact leaves */
168 xfs_dir2_data_t *data; /* data block structure */ 168 xfs_dir2_data_t *data; /* data block structure */
169 xfs_dabuf_t *dbp; /* data block buffer */ 169 xfs_dabuf_t *dbp; /* data block buffer */
170 xfs_dir2_data_entry_t *dep; /* data block entry */ 170 xfs_dir2_data_entry_t *dep; /* data block entry */
171 xfs_inode_t *dp; /* incore directory inode */ 171 xfs_inode_t *dp; /* incore directory inode */
172 xfs_dir2_data_unused_t *dup; /* data unused entry */ 172 xfs_dir2_data_unused_t *dup; /* data unused entry */
173 int error; /* error return value */ 173 int error; /* error return value */
174 int grown; /* allocated new data block */ 174 int grown; /* allocated new data block */
175 int highstale; /* index of next stale leaf */ 175 int highstale; /* index of next stale leaf */
176 int i; /* temporary, index */ 176 int i; /* temporary, index */
177 int index; /* leaf table position */ 177 int index; /* leaf table position */
178 xfs_dabuf_t *lbp; /* leaf's buffer */ 178 xfs_dabuf_t *lbp; /* leaf's buffer */
179 xfs_dir2_leaf_t *leaf; /* leaf structure */ 179 xfs_dir2_leaf_t *leaf; /* leaf structure */
180 int length; /* length of new entry */ 180 int length; /* length of new entry */
181 xfs_dir2_leaf_entry_t *lep; /* leaf entry table pointer */ 181 xfs_dir2_leaf_entry_t *lep; /* leaf entry table pointer */
182 int lfloglow; /* low leaf logging index */ 182 int lfloglow; /* low leaf logging index */
183 int lfloghigh; /* high leaf logging index */ 183 int lfloghigh; /* high leaf logging index */
184 int lowstale; /* index of prev stale leaf */ 184 int lowstale; /* index of prev stale leaf */
185 xfs_dir2_leaf_tail_t *ltp; /* leaf tail pointer */ 185 xfs_dir2_leaf_tail_t *ltp; /* leaf tail pointer */
186 xfs_mount_t *mp; /* filesystem mount point */ 186 xfs_mount_t *mp; /* filesystem mount point */
187 int needbytes; /* leaf block bytes needed */ 187 int needbytes; /* leaf block bytes needed */
188 int needlog; /* need to log data header */ 188 int needlog; /* need to log data header */
189 int needscan; /* need to rescan data free */ 189 int needscan; /* need to rescan data free */
190 xfs_dir2_data_off_t *tagp; /* end of data entry */ 190 xfs_dir2_data_off_t *tagp; /* end of data entry */
191 xfs_trans_t *tp; /* transaction pointer */ 191 xfs_trans_t *tp; /* transaction pointer */
192 xfs_dir2_db_t use_block; /* data block number */ 192 xfs_dir2_db_t use_block; /* data block number */
193 193
194 xfs_dir2_trace_args("leaf_addname", args); 194 xfs_dir2_trace_args("leaf_addname", args);
195 dp = args->dp; 195 dp = args->dp;
196 tp = args->trans; 196 tp = args->trans;
197 mp = dp->i_mount; 197 mp = dp->i_mount;
198 /* 198 /*
199 * Read the leaf block. 199 * Read the leaf block.
200 */ 200 */
201 error = xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp, 201 error = xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp,
202 XFS_DATA_FORK); 202 XFS_DATA_FORK);
203 if (error) { 203 if (error) {
204 return error; 204 return error;
205 } 205 }
206 ASSERT(lbp != NULL); 206 ASSERT(lbp != NULL);
207 /* 207 /*
208 * Look up the entry by hash value and name. 208 * Look up the entry by hash value and name.
209 * We know it's not there, our caller has already done a lookup. 209 * We know it's not there, our caller has already done a lookup.
210 * So the index is of the entry to insert in front of. 210 * So the index is of the entry to insert in front of.
211 * But if there are dup hash values the index is of the first of those. 211 * But if there are dup hash values the index is of the first of those.
212 */ 212 */
213 index = xfs_dir2_leaf_search_hash(args, lbp); 213 index = xfs_dir2_leaf_search_hash(args, lbp);
214 leaf = lbp->data; 214 leaf = lbp->data;
215 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); 215 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
216 bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); 216 bestsp = XFS_DIR2_LEAF_BESTS_P(ltp);
217 length = XFS_DIR2_DATA_ENTSIZE(args->namelen); 217 length = XFS_DIR2_DATA_ENTSIZE(args->namelen);
218 /* 218 /*
219 * See if there are any entries with the same hash value 219 * See if there are any entries with the same hash value
220 * and space in their block for the new entry. 220 * and space in their block for the new entry.
221 * This is good because it puts multiple same-hash value entries 221 * This is good because it puts multiple same-hash value entries
222 * in a data block, improving the lookup of those entries. 222 * in a data block, improving the lookup of those entries.
223 */ 223 */
224 for (use_block = -1, lep = &leaf->ents[index]; 224 for (use_block = -1, lep = &leaf->ents[index];
225 index < INT_GET(leaf->hdr.count, ARCH_CONVERT) && INT_GET(lep->hashval, ARCH_CONVERT) == args->hashval; 225 index < INT_GET(leaf->hdr.count, ARCH_CONVERT) && INT_GET(lep->hashval, ARCH_CONVERT) == args->hashval;
226 index++, lep++) { 226 index++, lep++) {
227 if (INT_GET(lep->address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) 227 if (INT_GET(lep->address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
228 continue; 228 continue;
229 i = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT)); 229 i = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT));
230 ASSERT(i < INT_GET(ltp->bestcount, ARCH_CONVERT)); 230 ASSERT(i < INT_GET(ltp->bestcount, ARCH_CONVERT));
231 ASSERT(INT_GET(bestsp[i], ARCH_CONVERT) != NULLDATAOFF); 231 ASSERT(INT_GET(bestsp[i], ARCH_CONVERT) != NULLDATAOFF);
232 if (INT_GET(bestsp[i], ARCH_CONVERT) >= length) { 232 if (INT_GET(bestsp[i], ARCH_CONVERT) >= length) {
233 use_block = i; 233 use_block = i;
234 break; 234 break;
235 } 235 }
236 } 236 }
237 /* 237 /*
238 * Didn't find a block yet, linear search all the data blocks. 238 * Didn't find a block yet, linear search all the data blocks.
239 */ 239 */
240 if (use_block == -1) { 240 if (use_block == -1) {
241 for (i = 0; i < INT_GET(ltp->bestcount, ARCH_CONVERT); i++) { 241 for (i = 0; i < INT_GET(ltp->bestcount, ARCH_CONVERT); i++) {
242 /* 242 /*
243 * Remember a block we see that's missing. 243 * Remember a block we see that's missing.
244 */ 244 */
245 if (INT_GET(bestsp[i], ARCH_CONVERT) == NULLDATAOFF && use_block == -1) 245 if (INT_GET(bestsp[i], ARCH_CONVERT) == NULLDATAOFF && use_block == -1)
246 use_block = i; 246 use_block = i;
247 else if (INT_GET(bestsp[i], ARCH_CONVERT) >= length) { 247 else if (INT_GET(bestsp[i], ARCH_CONVERT) >= length) {
248 use_block = i; 248 use_block = i;
249 break; 249 break;
250 } 250 }
251 } 251 }
252 } 252 }
253 /* 253 /*
254 * How many bytes do we need in the leaf block? 254 * How many bytes do we need in the leaf block?
255 */ 255 */
256 needbytes = 256 needbytes =
257 (leaf->hdr.stale ? 0 : (uint)sizeof(leaf->ents[0])) + 257 (leaf->hdr.stale ? 0 : (uint)sizeof(leaf->ents[0])) +
258 (use_block != -1 ? 0 : (uint)sizeof(leaf->bests[0])); 258 (use_block != -1 ? 0 : (uint)sizeof(leaf->bests[0]));
259 /* 259 /*
260 * Now kill use_block if it refers to a missing block, so we 260 * Now kill use_block if it refers to a missing block, so we
261 * can use it as an indication of allocation needed. 261 * can use it as an indication of allocation needed.
262 */ 262 */
263 if (use_block != -1 && INT_GET(bestsp[use_block], ARCH_CONVERT) == NULLDATAOFF) 263 if (use_block != -1 && INT_GET(bestsp[use_block], ARCH_CONVERT) == NULLDATAOFF)
264 use_block = -1; 264 use_block = -1;
265 /* 265 /*
266 * If we don't have enough free bytes but we can make enough 266 * If we don't have enough free bytes but we can make enough
267 * by compacting out stale entries, we'll do that. 267 * by compacting out stale entries, we'll do that.
268 */ 268 */
269 if ((char *)bestsp - (char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] < needbytes && 269 if ((char *)bestsp - (char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] < needbytes &&
270 INT_GET(leaf->hdr.stale, ARCH_CONVERT) > 1) { 270 INT_GET(leaf->hdr.stale, ARCH_CONVERT) > 1) {
271 compact = 1; 271 compact = 1;
272 } 272 }
273 /* 273 /*
274 * Otherwise if we don't have enough free bytes we need to 274 * Otherwise if we don't have enough free bytes we need to
275 * convert to node form. 275 * convert to node form.
276 */ 276 */
277 else if ((char *)bestsp - (char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] < 277 else if ((char *)bestsp - (char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] <
278 needbytes) { 278 needbytes) {
279 /* 279 /*
280 * Just checking or no space reservation, give up. 280 * Just checking or no space reservation, give up.
281 */ 281 */
282 if (args->justcheck || args->total == 0) { 282 if (args->justcheck || args->total == 0) {
283 xfs_da_brelse(tp, lbp); 283 xfs_da_brelse(tp, lbp);
284 return XFS_ERROR(ENOSPC); 284 return XFS_ERROR(ENOSPC);
285 } 285 }
286 /* 286 /*
287 * Convert to node form. 287 * Convert to node form.
288 */ 288 */
289 error = xfs_dir2_leaf_to_node(args, lbp); 289 error = xfs_dir2_leaf_to_node(args, lbp);
290 xfs_da_buf_done(lbp); 290 xfs_da_buf_done(lbp);
291 if (error) 291 if (error)
292 return error; 292 return error;
293 /* 293 /*
294 * Then add the new entry. 294 * Then add the new entry.
295 */ 295 */
296 return xfs_dir2_node_addname(args); 296 return xfs_dir2_node_addname(args);
297 } 297 }
298 /* 298 /*
299 * Otherwise it will fit without compaction. 299 * Otherwise it will fit without compaction.
300 */ 300 */
301 else 301 else
302 compact = 0; 302 compact = 0;
303 /* 303 /*
304 * If just checking, then it will fit unless we needed to allocate 304 * If just checking, then it will fit unless we needed to allocate
305 * a new data block. 305 * a new data block.
306 */ 306 */
307 if (args->justcheck) { 307 if (args->justcheck) {
308 xfs_da_brelse(tp, lbp); 308 xfs_da_brelse(tp, lbp);
309 return use_block == -1 ? XFS_ERROR(ENOSPC) : 0; 309 return use_block == -1 ? XFS_ERROR(ENOSPC) : 0;
310 } 310 }
311 /* 311 /*
312 * If no allocations are allowed, return now before we've 312 * If no allocations are allowed, return now before we've
313 * changed anything. 313 * changed anything.
314 */ 314 */
315 if (args->total == 0 && use_block == -1) { 315 if (args->total == 0 && use_block == -1) {
316 xfs_da_brelse(tp, lbp); 316 xfs_da_brelse(tp, lbp);
317 return XFS_ERROR(ENOSPC); 317 return XFS_ERROR(ENOSPC);
318 } 318 }
319 /* 319 /*
320 * Need to compact the leaf entries, removing stale ones. 320 * Need to compact the leaf entries, removing stale ones.
321 * Leave one stale entry behind - the one closest to our 321 * Leave one stale entry behind - the one closest to our
322 * insertion index - and we'll shift that one to our insertion 322 * insertion index - and we'll shift that one to our insertion
323 * point later. 323 * point later.
324 */ 324 */
325 if (compact) { 325 if (compact) {
326 xfs_dir2_leaf_compact_x1(lbp, &index, &lowstale, &highstale, 326 xfs_dir2_leaf_compact_x1(lbp, &index, &lowstale, &highstale,
327 &lfloglow, &lfloghigh); 327 &lfloglow, &lfloghigh);
328 } 328 }
329 /* 329 /*
330 * There are stale entries, so we'll need log-low and log-high 330 * There are stale entries, so we'll need log-low and log-high
331 * impossibly bad values later. 331 * impossibly bad values later.
332 */ 332 */
333 else if (INT_GET(leaf->hdr.stale, ARCH_CONVERT)) { 333 else if (INT_GET(leaf->hdr.stale, ARCH_CONVERT)) {
334 lfloglow = INT_GET(leaf->hdr.count, ARCH_CONVERT); 334 lfloglow = INT_GET(leaf->hdr.count, ARCH_CONVERT);
335 lfloghigh = -1; 335 lfloghigh = -1;
336 } 336 }
337 /* 337 /*
338 * If there was no data block space found, we need to allocate 338 * If there was no data block space found, we need to allocate
339 * a new one. 339 * a new one.
340 */ 340 */
341 if (use_block == -1) { 341 if (use_block == -1) {
342 /* 342 /*
343 * Add the new data block. 343 * Add the new data block.
344 */ 344 */
345 if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, 345 if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE,
346 &use_block))) { 346 &use_block))) {
347 xfs_da_brelse(tp, lbp); 347 xfs_da_brelse(tp, lbp);
348 return error; 348 return error;
349 } 349 }
350 /* 350 /*
351 * Initialize the block. 351 * Initialize the block.
352 */ 352 */
353 if ((error = xfs_dir2_data_init(args, use_block, &dbp))) { 353 if ((error = xfs_dir2_data_init(args, use_block, &dbp))) {
354 xfs_da_brelse(tp, lbp); 354 xfs_da_brelse(tp, lbp);
355 return error; 355 return error;
356 } 356 }
357 /* 357 /*
358 * If we're adding a new data block on the end we need to 358 * If we're adding a new data block on the end we need to
359 * extend the bests table. Copy it up one entry. 359 * extend the bests table. Copy it up one entry.
360 */ 360 */
361 if (use_block >= INT_GET(ltp->bestcount, ARCH_CONVERT)) { 361 if (use_block >= INT_GET(ltp->bestcount, ARCH_CONVERT)) {
362 bestsp--; 362 bestsp--;
363 memmove(&bestsp[0], &bestsp[1], 363 memmove(&bestsp[0], &bestsp[1],
364 INT_GET(ltp->bestcount, ARCH_CONVERT) * sizeof(bestsp[0])); 364 INT_GET(ltp->bestcount, ARCH_CONVERT) * sizeof(bestsp[0]));
365 INT_MOD(ltp->bestcount, ARCH_CONVERT, +1); 365 INT_MOD(ltp->bestcount, ARCH_CONVERT, +1);
366 xfs_dir2_leaf_log_tail(tp, lbp); 366 xfs_dir2_leaf_log_tail(tp, lbp);
367 xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1); 367 xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1);
368 } 368 }
369 /* 369 /*
370 * If we're filling in a previously empty block just log it. 370 * If we're filling in a previously empty block just log it.
371 */ 371 */
372 else 372 else
373 xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); 373 xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block);
374 data = dbp->data; 374 data = dbp->data;
375 INT_COPY(bestsp[use_block], data->hdr.bestfree[0].length, ARCH_CONVERT); 375 bestsp[use_block] = data->hdr.bestfree[0].length;
376 grown = 1; 376 grown = 1;
377 } 377 }
378 /* 378 /*
379 * Already had space in some data block. 379 * Already had space in some data block.
380 * Just read that one in. 380 * Just read that one in.
381 */ 381 */
382 else { 382 else {
383 if ((error = 383 if ((error =
384 xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, use_block), 384 xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, use_block),
385 -1, &dbp, XFS_DATA_FORK))) { 385 -1, &dbp, XFS_DATA_FORK))) {
386 xfs_da_brelse(tp, lbp); 386 xfs_da_brelse(tp, lbp);
387 return error; 387 return error;
388 } 388 }
389 data = dbp->data; 389 data = dbp->data;
390 grown = 0; 390 grown = 0;
391 } 391 }
392 xfs_dir2_data_check(dp, dbp); 392 xfs_dir2_data_check(dp, dbp);
393 /* 393 /*
394 * Point to the biggest freespace in our data block. 394 * Point to the biggest freespace in our data block.
395 */ 395 */
396 dup = (xfs_dir2_data_unused_t *) 396 dup = (xfs_dir2_data_unused_t *)
397 ((char *)data + INT_GET(data->hdr.bestfree[0].offset, ARCH_CONVERT)); 397 ((char *)data + be16_to_cpu(data->hdr.bestfree[0].offset));
398 ASSERT(INT_GET(dup->length, ARCH_CONVERT) >= length); 398 ASSERT(INT_GET(dup->length, ARCH_CONVERT) >= length);
399 needscan = needlog = 0; 399 needscan = needlog = 0;
400 /* 400 /*
401 * Mark the initial part of our freespace in use for the new entry. 401 * Mark the initial part of our freespace in use for the new entry.
402 */ 402 */
403 xfs_dir2_data_use_free(tp, dbp, dup, 403 xfs_dir2_data_use_free(tp, dbp, dup,
404 (xfs_dir2_data_aoff_t)((char *)dup - (char *)data), length, 404 (xfs_dir2_data_aoff_t)((char *)dup - (char *)data), length,
405 &needlog, &needscan); 405 &needlog, &needscan);
406 /* 406 /*
407 * Initialize our new entry (at last). 407 * Initialize our new entry (at last).
408 */ 408 */
409 dep = (xfs_dir2_data_entry_t *)dup; 409 dep = (xfs_dir2_data_entry_t *)dup;
410 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 410 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
411 dep->namelen = args->namelen; 411 dep->namelen = args->namelen;
412 memcpy(dep->name, args->name, dep->namelen); 412 memcpy(dep->name, args->name, dep->namelen);
413 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 413 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
414 INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)data)); 414 INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)data));
415 /* 415 /*
416 * Need to scan fix up the bestfree table. 416 * Need to scan fix up the bestfree table.
417 */ 417 */
418 if (needscan) 418 if (needscan)
419 xfs_dir2_data_freescan(mp, data, &needlog, NULL); 419 xfs_dir2_data_freescan(mp, data, &needlog, NULL);
420 /* 420 /*
421 * Need to log the data block's header. 421 * Need to log the data block's header.
422 */ 422 */
423 if (needlog) 423 if (needlog)
424 xfs_dir2_data_log_header(tp, dbp); 424 xfs_dir2_data_log_header(tp, dbp);
425 xfs_dir2_data_log_entry(tp, dbp, dep); 425 xfs_dir2_data_log_entry(tp, dbp, dep);
426 /* 426 /*
427 * If the bests table needs to be changed, do it. 427 * If the bests table needs to be changed, do it.
428 * Log the change unless we've already done that. 428 * Log the change unless we've already done that.
429 */ 429 */
430 if (INT_GET(bestsp[use_block], ARCH_CONVERT) != INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT)) { 430 if (INT_GET(bestsp[use_block], ARCH_CONVERT) != be16_to_cpu(data->hdr.bestfree[0].length)) {
431 INT_COPY(bestsp[use_block], data->hdr.bestfree[0].length, ARCH_CONVERT); 431 bestsp[use_block] = data->hdr.bestfree[0].length;
432 if (!grown) 432 if (!grown)
433 xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); 433 xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block);
434 } 434 }
435 /* 435 /*
436 * Now we need to make room to insert the leaf entry. 436 * Now we need to make room to insert the leaf entry.
437 * If there are no stale entries, we just insert a hole at index. 437 * If there are no stale entries, we just insert a hole at index.
438 */ 438 */
439 if (!leaf->hdr.stale) { 439 if (!leaf->hdr.stale) {
440 /* 440 /*
441 * lep is still good as the index leaf entry. 441 * lep is still good as the index leaf entry.
442 */ 442 */
443 if (index < INT_GET(leaf->hdr.count, ARCH_CONVERT)) 443 if (index < INT_GET(leaf->hdr.count, ARCH_CONVERT))
444 memmove(lep + 1, lep, 444 memmove(lep + 1, lep,
445 (INT_GET(leaf->hdr.count, ARCH_CONVERT) - index) * sizeof(*lep)); 445 (INT_GET(leaf->hdr.count, ARCH_CONVERT) - index) * sizeof(*lep));
446 /* 446 /*
447 * Record low and high logging indices for the leaf. 447 * Record low and high logging indices for the leaf.
448 */ 448 */
449 lfloglow = index; 449 lfloglow = index;
450 lfloghigh = INT_GET(leaf->hdr.count, ARCH_CONVERT); 450 lfloghigh = INT_GET(leaf->hdr.count, ARCH_CONVERT);
451 INT_MOD(leaf->hdr.count, ARCH_CONVERT, +1); 451 INT_MOD(leaf->hdr.count, ARCH_CONVERT, +1);
452 } 452 }
453 /* 453 /*
454 * There are stale entries. 454 * There are stale entries.
455 * We will use one of them for the new entry. 455 * We will use one of them for the new entry.
456 * It's probably not at the right location, so we'll have to 456 * It's probably not at the right location, so we'll have to
457 * shift some up or down first. 457 * shift some up or down first.
458 */ 458 */
459 else { 459 else {
460 /* 460 /*
461 * If we didn't compact before, we need to find the nearest 461 * If we didn't compact before, we need to find the nearest
462 * stale entries before and after our insertion point. 462 * stale entries before and after our insertion point.
463 */ 463 */
464 if (compact == 0) { 464 if (compact == 0) {
465 /* 465 /*
466 * Find the first stale entry before the insertion 466 * Find the first stale entry before the insertion
467 * point, if any. 467 * point, if any.
468 */ 468 */
469 for (lowstale = index - 1; 469 for (lowstale = index - 1;
470 lowstale >= 0 && 470 lowstale >= 0 &&
471 INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) != 471 INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) !=
472 XFS_DIR2_NULL_DATAPTR; 472 XFS_DIR2_NULL_DATAPTR;
473 lowstale--) 473 lowstale--)
474 continue; 474 continue;
475 /* 475 /*
476 * Find the next stale entry at or after the insertion 476 * Find the next stale entry at or after the insertion
477 * point, if any. Stop if we go so far that the 477 * point, if any. Stop if we go so far that the
478 * lowstale entry would be better. 478 * lowstale entry would be better.
479 */ 479 */
480 for (highstale = index; 480 for (highstale = index;
481 highstale < INT_GET(leaf->hdr.count, ARCH_CONVERT) && 481 highstale < INT_GET(leaf->hdr.count, ARCH_CONVERT) &&
482 INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) != 482 INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) !=
483 XFS_DIR2_NULL_DATAPTR && 483 XFS_DIR2_NULL_DATAPTR &&
484 (lowstale < 0 || 484 (lowstale < 0 ||
485 index - lowstale - 1 >= highstale - index); 485 index - lowstale - 1 >= highstale - index);
486 highstale++) 486 highstale++)
487 continue; 487 continue;
488 } 488 }
489 /* 489 /*
490 * If the low one is better, use it. 490 * If the low one is better, use it.
491 */ 491 */
492 if (lowstale >= 0 && 492 if (lowstale >= 0 &&
493 (highstale == INT_GET(leaf->hdr.count, ARCH_CONVERT) || 493 (highstale == INT_GET(leaf->hdr.count, ARCH_CONVERT) ||
494 index - lowstale - 1 < highstale - index)) { 494 index - lowstale - 1 < highstale - index)) {
495 ASSERT(index - lowstale - 1 >= 0); 495 ASSERT(index - lowstale - 1 >= 0);
496 ASSERT(INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) == 496 ASSERT(INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) ==
497 XFS_DIR2_NULL_DATAPTR); 497 XFS_DIR2_NULL_DATAPTR);
498 /* 498 /*
499 * Copy entries up to cover the stale entry 499 * Copy entries up to cover the stale entry
500 * and make room for the new entry. 500 * and make room for the new entry.
501 */ 501 */
502 if (index - lowstale - 1 > 0) 502 if (index - lowstale - 1 > 0)
503 memmove(&leaf->ents[lowstale], 503 memmove(&leaf->ents[lowstale],
504 &leaf->ents[lowstale + 1], 504 &leaf->ents[lowstale + 1],
505 (index - lowstale - 1) * sizeof(*lep)); 505 (index - lowstale - 1) * sizeof(*lep));
506 lep = &leaf->ents[index - 1]; 506 lep = &leaf->ents[index - 1];
507 lfloglow = MIN(lowstale, lfloglow); 507 lfloglow = MIN(lowstale, lfloglow);
508 lfloghigh = MAX(index - 1, lfloghigh); 508 lfloghigh = MAX(index - 1, lfloghigh);
509 } 509 }
510 /* 510 /*
511 * The high one is better, so use that one. 511 * The high one is better, so use that one.
512 */ 512 */
513 else { 513 else {
514 ASSERT(highstale - index >= 0); 514 ASSERT(highstale - index >= 0);
515 ASSERT(INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) == 515 ASSERT(INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) ==
516 XFS_DIR2_NULL_DATAPTR); 516 XFS_DIR2_NULL_DATAPTR);
517 /* 517 /*
518 * Copy entries down to copver the stale entry 518 * Copy entries down to copver the stale entry
519 * and make room for the new entry. 519 * and make room for the new entry.
520 */ 520 */
521 if (highstale - index > 0) 521 if (highstale - index > 0)
522 memmove(&leaf->ents[index + 1], 522 memmove(&leaf->ents[index + 1],
523 &leaf->ents[index], 523 &leaf->ents[index],
524 (highstale - index) * sizeof(*lep)); 524 (highstale - index) * sizeof(*lep));
525 lep = &leaf->ents[index]; 525 lep = &leaf->ents[index];
526 lfloglow = MIN(index, lfloglow); 526 lfloglow = MIN(index, lfloglow);
527 lfloghigh = MAX(highstale, lfloghigh); 527 lfloghigh = MAX(highstale, lfloghigh);
528 } 528 }
529 INT_MOD(leaf->hdr.stale, ARCH_CONVERT, -1); 529 INT_MOD(leaf->hdr.stale, ARCH_CONVERT, -1);
530 } 530 }
531 /* 531 /*
532 * Fill in the new leaf entry. 532 * Fill in the new leaf entry.
533 */ 533 */
534 INT_SET(lep->hashval, ARCH_CONVERT, args->hashval); 534 INT_SET(lep->hashval, ARCH_CONVERT, args->hashval);
535 INT_SET(lep->address, ARCH_CONVERT, XFS_DIR2_DB_OFF_TO_DATAPTR(mp, use_block, INT_GET(*tagp, ARCH_CONVERT))); 535 INT_SET(lep->address, ARCH_CONVERT, XFS_DIR2_DB_OFF_TO_DATAPTR(mp, use_block, INT_GET(*tagp, ARCH_CONVERT)));
536 /* 536 /*
537 * Log the leaf fields and give up the buffers. 537 * Log the leaf fields and give up the buffers.
538 */ 538 */
539 xfs_dir2_leaf_log_header(tp, lbp); 539 xfs_dir2_leaf_log_header(tp, lbp);
540 xfs_dir2_leaf_log_ents(tp, lbp, lfloglow, lfloghigh); 540 xfs_dir2_leaf_log_ents(tp, lbp, lfloglow, lfloghigh);
541 xfs_dir2_leaf_check(dp, lbp); 541 xfs_dir2_leaf_check(dp, lbp);
542 xfs_da_buf_done(lbp); 542 xfs_da_buf_done(lbp);
543 xfs_dir2_data_check(dp, dbp); 543 xfs_dir2_data_check(dp, dbp);
544 xfs_da_buf_done(dbp); 544 xfs_da_buf_done(dbp);
545 return 0; 545 return 0;
546 } 546 }
547 547
548 #ifdef DEBUG 548 #ifdef DEBUG
549 /* 549 /*
550 * Check the internal consistency of a leaf1 block. 550 * Check the internal consistency of a leaf1 block.
551 * Pop an assert if something is wrong. 551 * Pop an assert if something is wrong.
552 */ 552 */
553 void 553 void
554 xfs_dir2_leaf_check( 554 xfs_dir2_leaf_check(
555 xfs_inode_t *dp, /* incore directory inode */ 555 xfs_inode_t *dp, /* incore directory inode */
556 xfs_dabuf_t *bp) /* leaf's buffer */ 556 xfs_dabuf_t *bp) /* leaf's buffer */
557 { 557 {
558 int i; /* leaf index */ 558 int i; /* leaf index */
559 xfs_dir2_leaf_t *leaf; /* leaf structure */ 559 xfs_dir2_leaf_t *leaf; /* leaf structure */
560 xfs_dir2_leaf_tail_t *ltp; /* leaf tail pointer */ 560 xfs_dir2_leaf_tail_t *ltp; /* leaf tail pointer */
561 xfs_mount_t *mp; /* filesystem mount point */ 561 xfs_mount_t *mp; /* filesystem mount point */
562 int stale; /* count of stale leaves */ 562 int stale; /* count of stale leaves */
563 563
564 leaf = bp->data; 564 leaf = bp->data;
565 mp = dp->i_mount; 565 mp = dp->i_mount;
566 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC); 566 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC);
567 /* 567 /*
568 * This value is not restrictive enough. 568 * This value is not restrictive enough.
569 * Should factor in the size of the bests table as well. 569 * Should factor in the size of the bests table as well.
570 * We can deduce a value for that from di_size. 570 * We can deduce a value for that from di_size.
571 */ 571 */
572 ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) <= XFS_DIR2_MAX_LEAF_ENTS(mp)); 572 ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) <= XFS_DIR2_MAX_LEAF_ENTS(mp));
573 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); 573 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
574 /* 574 /*
575 * Leaves and bests don't overlap. 575 * Leaves and bests don't overlap.
576 */ 576 */
577 ASSERT((char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] <= 577 ASSERT((char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] <=
578 (char *)XFS_DIR2_LEAF_BESTS_P(ltp)); 578 (char *)XFS_DIR2_LEAF_BESTS_P(ltp));
579 /* 579 /*
580 * Check hash value order, count stale entries. 580 * Check hash value order, count stale entries.
581 */ 581 */
582 for (i = stale = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); i++) { 582 for (i = stale = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); i++) {
583 if (i + 1 < INT_GET(leaf->hdr.count, ARCH_CONVERT)) 583 if (i + 1 < INT_GET(leaf->hdr.count, ARCH_CONVERT))
584 ASSERT(INT_GET(leaf->ents[i].hashval, ARCH_CONVERT) <= 584 ASSERT(INT_GET(leaf->ents[i].hashval, ARCH_CONVERT) <=
585 INT_GET(leaf->ents[i + 1].hashval, ARCH_CONVERT)); 585 INT_GET(leaf->ents[i + 1].hashval, ARCH_CONVERT));
586 if (INT_GET(leaf->ents[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) 586 if (INT_GET(leaf->ents[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
587 stale++; 587 stale++;
588 } 588 }
589 ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) == stale); 589 ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) == stale);
590 } 590 }
591 #endif /* DEBUG */ 591 #endif /* DEBUG */
592 592
593 /* 593 /*
594 * Compact out any stale entries in the leaf. 594 * Compact out any stale entries in the leaf.
595 * Log the header and changed leaf entries, if any. 595 * Log the header and changed leaf entries, if any.
596 */ 596 */
597 void 597 void
598 xfs_dir2_leaf_compact( 598 xfs_dir2_leaf_compact(
599 xfs_da_args_t *args, /* operation arguments */ 599 xfs_da_args_t *args, /* operation arguments */
600 xfs_dabuf_t *bp) /* leaf buffer */ 600 xfs_dabuf_t *bp) /* leaf buffer */
601 { 601 {
602 int from; /* source leaf index */ 602 int from; /* source leaf index */
603 xfs_dir2_leaf_t *leaf; /* leaf structure */ 603 xfs_dir2_leaf_t *leaf; /* leaf structure */
604 int loglow; /* first leaf entry to log */ 604 int loglow; /* first leaf entry to log */
605 int to; /* target leaf index */ 605 int to; /* target leaf index */
606 606
607 leaf = bp->data; 607 leaf = bp->data;
608 if (!leaf->hdr.stale) { 608 if (!leaf->hdr.stale) {
609 return; 609 return;
610 } 610 }
611 /* 611 /*
612 * Compress out the stale entries in place. 612 * Compress out the stale entries in place.
613 */ 613 */
614 for (from = to = 0, loglow = -1; from < INT_GET(leaf->hdr.count, ARCH_CONVERT); from++) { 614 for (from = to = 0, loglow = -1; from < INT_GET(leaf->hdr.count, ARCH_CONVERT); from++) {
615 if (INT_GET(leaf->ents[from].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) 615 if (INT_GET(leaf->ents[from].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
616 continue; 616 continue;
617 /* 617 /*
618 * Only actually copy the entries that are different. 618 * Only actually copy the entries that are different.
619 */ 619 */
620 if (from > to) { 620 if (from > to) {
621 if (loglow == -1) 621 if (loglow == -1)
622 loglow = to; 622 loglow = to;
623 leaf->ents[to] = leaf->ents[from]; 623 leaf->ents[to] = leaf->ents[from];
624 } 624 }
625 to++; 625 to++;
626 } 626 }
627 /* 627 /*
628 * Update and log the header, log the leaf entries. 628 * Update and log the header, log the leaf entries.
629 */ 629 */
630 ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) == from - to); 630 ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) == from - to);
631 INT_MOD(leaf->hdr.count, ARCH_CONVERT, -(INT_GET(leaf->hdr.stale, ARCH_CONVERT))); 631 INT_MOD(leaf->hdr.count, ARCH_CONVERT, -(INT_GET(leaf->hdr.stale, ARCH_CONVERT)));
632 leaf->hdr.stale = 0; 632 leaf->hdr.stale = 0;
633 xfs_dir2_leaf_log_header(args->trans, bp); 633 xfs_dir2_leaf_log_header(args->trans, bp);
634 if (loglow != -1) 634 if (loglow != -1)
635 xfs_dir2_leaf_log_ents(args->trans, bp, loglow, to - 1); 635 xfs_dir2_leaf_log_ents(args->trans, bp, loglow, to - 1);
636 } 636 }
637 637
638 /* 638 /*
639 * Compact the leaf entries, removing stale ones. 639 * Compact the leaf entries, removing stale ones.
640 * Leave one stale entry behind - the one closest to our 640 * Leave one stale entry behind - the one closest to our
641 * insertion index - and the caller will shift that one to our insertion 641 * insertion index - and the caller will shift that one to our insertion
642 * point later. 642 * point later.
643 * Return new insertion index, where the remaining stale entry is, 643 * Return new insertion index, where the remaining stale entry is,
644 * and leaf logging indices. 644 * and leaf logging indices.
645 */ 645 */
646 void 646 void
647 xfs_dir2_leaf_compact_x1( 647 xfs_dir2_leaf_compact_x1(
648 xfs_dabuf_t *bp, /* leaf buffer */ 648 xfs_dabuf_t *bp, /* leaf buffer */
649 int *indexp, /* insertion index */ 649 int *indexp, /* insertion index */
650 int *lowstalep, /* out: stale entry before us */ 650 int *lowstalep, /* out: stale entry before us */
651 int *highstalep, /* out: stale entry after us */ 651 int *highstalep, /* out: stale entry after us */
652 int *lowlogp, /* out: low log index */ 652 int *lowlogp, /* out: low log index */
653 int *highlogp) /* out: high log index */ 653 int *highlogp) /* out: high log index */
654 { 654 {
655 int from; /* source copy index */ 655 int from; /* source copy index */
656 int highstale; /* stale entry at/after index */ 656 int highstale; /* stale entry at/after index */
657 int index; /* insertion index */ 657 int index; /* insertion index */
658 int keepstale; /* source index of kept stale */ 658 int keepstale; /* source index of kept stale */
659 xfs_dir2_leaf_t *leaf; /* leaf structure */ 659 xfs_dir2_leaf_t *leaf; /* leaf structure */
660 int lowstale; /* stale entry before index */ 660 int lowstale; /* stale entry before index */
661 int newindex=0; /* new insertion index */ 661 int newindex=0; /* new insertion index */
662 int to; /* destination copy index */ 662 int to; /* destination copy index */
663 663
664 leaf = bp->data; 664 leaf = bp->data;
665 ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) > 1); 665 ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) > 1);
666 index = *indexp; 666 index = *indexp;
667 /* 667 /*
668 * Find the first stale entry before our index, if any. 668 * Find the first stale entry before our index, if any.
669 */ 669 */
670 for (lowstale = index - 1; 670 for (lowstale = index - 1;
671 lowstale >= 0 && 671 lowstale >= 0 &&
672 INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) != XFS_DIR2_NULL_DATAPTR; 672 INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) != XFS_DIR2_NULL_DATAPTR;
673 lowstale--) 673 lowstale--)
674 continue; 674 continue;
675 /* 675 /*
676 * Find the first stale entry at or after our index, if any. 676 * Find the first stale entry at or after our index, if any.
677 * Stop if the answer would be worse than lowstale. 677 * Stop if the answer would be worse than lowstale.
678 */ 678 */
679 for (highstale = index; 679 for (highstale = index;
680 highstale < INT_GET(leaf->hdr.count, ARCH_CONVERT) && 680 highstale < INT_GET(leaf->hdr.count, ARCH_CONVERT) &&
681 INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) != XFS_DIR2_NULL_DATAPTR && 681 INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) != XFS_DIR2_NULL_DATAPTR &&
682 (lowstale < 0 || index - lowstale > highstale - index); 682 (lowstale < 0 || index - lowstale > highstale - index);
683 highstale++) 683 highstale++)
684 continue; 684 continue;
685 /* 685 /*
686 * Pick the better of lowstale and highstale. 686 * Pick the better of lowstale and highstale.
687 */ 687 */
688 if (lowstale >= 0 && 688 if (lowstale >= 0 &&
689 (highstale == INT_GET(leaf->hdr.count, ARCH_CONVERT) || 689 (highstale == INT_GET(leaf->hdr.count, ARCH_CONVERT) ||
690 index - lowstale <= highstale - index)) 690 index - lowstale <= highstale - index))
691 keepstale = lowstale; 691 keepstale = lowstale;
692 else 692 else
693 keepstale = highstale; 693 keepstale = highstale;
694 /* 694 /*
695 * Copy the entries in place, removing all the stale entries 695 * Copy the entries in place, removing all the stale entries
696 * except keepstale. 696 * except keepstale.
697 */ 697 */
698 for (from = to = 0; from < INT_GET(leaf->hdr.count, ARCH_CONVERT); from++) { 698 for (from = to = 0; from < INT_GET(leaf->hdr.count, ARCH_CONVERT); from++) {
699 /* 699 /*
700 * Notice the new value of index. 700 * Notice the new value of index.
701 */ 701 */
702 if (index == from) 702 if (index == from)
703 newindex = to; 703 newindex = to;
704 if (from != keepstale && 704 if (from != keepstale &&
705 INT_GET(leaf->ents[from].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) { 705 INT_GET(leaf->ents[from].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) {
706 if (from == to) 706 if (from == to)
707 *lowlogp = to; 707 *lowlogp = to;
708 continue; 708 continue;
709 } 709 }
710 /* 710 /*
711 * Record the new keepstale value for the insertion. 711 * Record the new keepstale value for the insertion.
712 */ 712 */
713 if (from == keepstale) 713 if (from == keepstale)
714 lowstale = highstale = to; 714 lowstale = highstale = to;
715 /* 715 /*
716 * Copy only the entries that have moved. 716 * Copy only the entries that have moved.
717 */ 717 */
718 if (from > to) 718 if (from > to)
719 leaf->ents[to] = leaf->ents[from]; 719 leaf->ents[to] = leaf->ents[from];
720 to++; 720 to++;
721 } 721 }
722 ASSERT(from > to); 722 ASSERT(from > to);
723 /* 723 /*
724 * If the insertion point was past the last entry, 724 * If the insertion point was past the last entry,
725 * set the new insertion point accordingly. 725 * set the new insertion point accordingly.
726 */ 726 */
727 if (index == from) 727 if (index == from)
728 newindex = to; 728 newindex = to;
729 *indexp = newindex; 729 *indexp = newindex;
730 /* 730 /*
731 * Adjust the leaf header values. 731 * Adjust the leaf header values.
732 */ 732 */
733 INT_MOD(leaf->hdr.count, ARCH_CONVERT, -(from - to)); 733 INT_MOD(leaf->hdr.count, ARCH_CONVERT, -(from - to));
734 INT_SET(leaf->hdr.stale, ARCH_CONVERT, 1); 734 INT_SET(leaf->hdr.stale, ARCH_CONVERT, 1);
735 /* 735 /*
736 * Remember the low/high stale value only in the "right" 736 * Remember the low/high stale value only in the "right"
737 * direction. 737 * direction.
738 */ 738 */
739 if (lowstale >= newindex) 739 if (lowstale >= newindex)
740 lowstale = -1; 740 lowstale = -1;
741 else 741 else
742 highstale = INT_GET(leaf->hdr.count, ARCH_CONVERT); 742 highstale = INT_GET(leaf->hdr.count, ARCH_CONVERT);
743 *highlogp = INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1; 743 *highlogp = INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1;
744 *lowstalep = lowstale; 744 *lowstalep = lowstale;
745 *highstalep = highstale; 745 *highstalep = highstale;
746 } 746 }
747 747
748 /* 748 /*
749 * Getdents (readdir) for leaf and node directories. 749 * Getdents (readdir) for leaf and node directories.
750 * This reads the data blocks only, so is the same for both forms. 750 * This reads the data blocks only, so is the same for both forms.
751 */ 751 */
752 int /* error */ 752 int /* error */
753 xfs_dir2_leaf_getdents( 753 xfs_dir2_leaf_getdents(
754 xfs_trans_t *tp, /* transaction pointer */ 754 xfs_trans_t *tp, /* transaction pointer */
755 xfs_inode_t *dp, /* incore directory inode */ 755 xfs_inode_t *dp, /* incore directory inode */
756 uio_t *uio, /* I/O control & vectors */ 756 uio_t *uio, /* I/O control & vectors */
757 int *eofp, /* out: reached end of dir */ 757 int *eofp, /* out: reached end of dir */
758 xfs_dirent_t *dbp, /* caller's buffer */ 758 xfs_dirent_t *dbp, /* caller's buffer */
759 xfs_dir2_put_t put) /* ABI formatting routine */ 759 xfs_dir2_put_t put) /* ABI formatting routine */
760 { 760 {
761 xfs_dabuf_t *bp; /* data block buffer */ 761 xfs_dabuf_t *bp; /* data block buffer */
762 int byteoff; /* offset in current block */ 762 int byteoff; /* offset in current block */
763 xfs_dir2_db_t curdb; /* db for current block */ 763 xfs_dir2_db_t curdb; /* db for current block */
764 xfs_dir2_off_t curoff; /* current overall offset */ 764 xfs_dir2_off_t curoff; /* current overall offset */
765 xfs_dir2_data_t *data; /* data block structure */ 765 xfs_dir2_data_t *data; /* data block structure */
766 xfs_dir2_data_entry_t *dep; /* data entry */ 766 xfs_dir2_data_entry_t *dep; /* data entry */
767 xfs_dir2_data_unused_t *dup; /* unused entry */ 767 xfs_dir2_data_unused_t *dup; /* unused entry */
768 int eof; /* reached end of directory */ 768 int eof; /* reached end of directory */
769 int error = 0; /* error return value */ 769 int error = 0; /* error return value */
770 int i; /* temporary loop index */ 770 int i; /* temporary loop index */
771 int j; /* temporary loop index */ 771 int j; /* temporary loop index */
772 int length; /* temporary length value */ 772 int length; /* temporary length value */
773 xfs_bmbt_irec_t *map; /* map vector for blocks */ 773 xfs_bmbt_irec_t *map; /* map vector for blocks */
774 xfs_extlen_t map_blocks; /* number of fsbs in map */ 774 xfs_extlen_t map_blocks; /* number of fsbs in map */
775 xfs_dablk_t map_off; /* last mapped file offset */ 775 xfs_dablk_t map_off; /* last mapped file offset */
776 int map_size; /* total entries in *map */ 776 int map_size; /* total entries in *map */
777 int map_valid; /* valid entries in *map */ 777 int map_valid; /* valid entries in *map */
778 xfs_mount_t *mp; /* filesystem mount point */ 778 xfs_mount_t *mp; /* filesystem mount point */
779 xfs_dir2_off_t newoff; /* new curoff after new blk */ 779 xfs_dir2_off_t newoff; /* new curoff after new blk */
780 int nmap; /* mappings to ask xfs_bmapi */ 780 int nmap; /* mappings to ask xfs_bmapi */
781 xfs_dir2_put_args_t *p; /* formatting arg bundle */ 781 xfs_dir2_put_args_t *p; /* formatting arg bundle */
782 char *ptr = NULL; /* pointer to current data */ 782 char *ptr = NULL; /* pointer to current data */
783 int ra_current; /* number of read-ahead blks */ 783 int ra_current; /* number of read-ahead blks */
784 int ra_index; /* *map index for read-ahead */ 784 int ra_index; /* *map index for read-ahead */
785 int ra_offset; /* map entry offset for ra */ 785 int ra_offset; /* map entry offset for ra */
786 int ra_want; /* readahead count wanted */ 786 int ra_want; /* readahead count wanted */
787 787
788 /* 788 /*
789 * If the offset is at or past the largest allowed value, 789 * If the offset is at or past the largest allowed value,
790 * give up right away, return eof. 790 * give up right away, return eof.
791 */ 791 */
792 if (uio->uio_offset >= XFS_DIR2_MAX_DATAPTR) { 792 if (uio->uio_offset >= XFS_DIR2_MAX_DATAPTR) {
793 *eofp = 1; 793 *eofp = 1;
794 return 0; 794 return 0;
795 } 795 }
796 mp = dp->i_mount; 796 mp = dp->i_mount;
797 /* 797 /*
798 * Setup formatting arguments. 798 * Setup formatting arguments.
799 */ 799 */
800 p = kmem_alloc(sizeof(*p), KM_SLEEP); 800 p = kmem_alloc(sizeof(*p), KM_SLEEP);
801 p->dbp = dbp; 801 p->dbp = dbp;
802 p->put = put; 802 p->put = put;
803 p->uio = uio; 803 p->uio = uio;
804 /* 804 /*
805 * Set up to bmap a number of blocks based on the caller's 805 * Set up to bmap a number of blocks based on the caller's
806 * buffer size, the directory block size, and the filesystem 806 * buffer size, the directory block size, and the filesystem
807 * block size. 807 * block size.
808 */ 808 */
809 map_size = 809 map_size =
810 howmany(uio->uio_resid + mp->m_dirblksize, 810 howmany(uio->uio_resid + mp->m_dirblksize,
811 mp->m_sb.sb_blocksize); 811 mp->m_sb.sb_blocksize);
812 map = kmem_alloc(map_size * sizeof(*map), KM_SLEEP); 812 map = kmem_alloc(map_size * sizeof(*map), KM_SLEEP);
813 map_valid = ra_index = ra_offset = ra_current = map_blocks = 0; 813 map_valid = ra_index = ra_offset = ra_current = map_blocks = 0;
814 bp = NULL; 814 bp = NULL;
815 eof = 1; 815 eof = 1;
816 /* 816 /*
817 * Inside the loop we keep the main offset value as a byte offset 817 * Inside the loop we keep the main offset value as a byte offset
818 * in the directory file. 818 * in the directory file.
819 */ 819 */
820 curoff = XFS_DIR2_DATAPTR_TO_BYTE(mp, uio->uio_offset); 820 curoff = XFS_DIR2_DATAPTR_TO_BYTE(mp, uio->uio_offset);
821 /* 821 /*
822 * Force this conversion through db so we truncate the offset 822 * Force this conversion through db so we truncate the offset
823 * down to get the start of the data block. 823 * down to get the start of the data block.
824 */ 824 */
825 map_off = XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_BYTE_TO_DB(mp, curoff)); 825 map_off = XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_BYTE_TO_DB(mp, curoff));
826 /* 826 /*
827 * Loop over directory entries until we reach the end offset. 827 * Loop over directory entries until we reach the end offset.
828 * Get more blocks and readahead as necessary. 828 * Get more blocks and readahead as necessary.
829 */ 829 */
830 while (curoff < XFS_DIR2_LEAF_OFFSET) { 830 while (curoff < XFS_DIR2_LEAF_OFFSET) {
831 /* 831 /*
832 * If we have no buffer, or we're off the end of the 832 * If we have no buffer, or we're off the end of the
833 * current buffer, need to get another one. 833 * current buffer, need to get another one.
834 */ 834 */
835 if (!bp || ptr >= (char *)bp->data + mp->m_dirblksize) { 835 if (!bp || ptr >= (char *)bp->data + mp->m_dirblksize) {
836 /* 836 /*
837 * If we have a buffer, we need to release it and 837 * If we have a buffer, we need to release it and
838 * take it out of the mapping. 838 * take it out of the mapping.
839 */ 839 */
840 if (bp) { 840 if (bp) {
841 xfs_da_brelse(tp, bp); 841 xfs_da_brelse(tp, bp);
842 bp = NULL; 842 bp = NULL;
843 map_blocks -= mp->m_dirblkfsbs; 843 map_blocks -= mp->m_dirblkfsbs;
844 /* 844 /*
845 * Loop to get rid of the extents for the 845 * Loop to get rid of the extents for the
846 * directory block. 846 * directory block.
847 */ 847 */
848 for (i = mp->m_dirblkfsbs; i > 0; ) { 848 for (i = mp->m_dirblkfsbs; i > 0; ) {
849 j = MIN((int)map->br_blockcount, i); 849 j = MIN((int)map->br_blockcount, i);
850 map->br_blockcount -= j; 850 map->br_blockcount -= j;
851 map->br_startblock += j; 851 map->br_startblock += j;
852 map->br_startoff += j; 852 map->br_startoff += j;
853 /* 853 /*
854 * If mapping is done, pitch it from 854 * If mapping is done, pitch it from
855 * the table. 855 * the table.
856 */ 856 */
857 if (!map->br_blockcount && --map_valid) 857 if (!map->br_blockcount && --map_valid)
858 memmove(&map[0], &map[1], 858 memmove(&map[0], &map[1],
859 sizeof(map[0]) * 859 sizeof(map[0]) *
860 map_valid); 860 map_valid);
861 i -= j; 861 i -= j;
862 } 862 }
863 } 863 }
864 /* 864 /*
865 * Recalculate the readahead blocks wanted. 865 * Recalculate the readahead blocks wanted.
866 */ 866 */
867 ra_want = howmany(uio->uio_resid + mp->m_dirblksize, 867 ra_want = howmany(uio->uio_resid + mp->m_dirblksize,
868 mp->m_sb.sb_blocksize) - 1; 868 mp->m_sb.sb_blocksize) - 1;
869 /* 869 /*
870 * If we don't have as many as we want, and we haven't 870 * If we don't have as many as we want, and we haven't
871 * run out of data blocks, get some more mappings. 871 * run out of data blocks, get some more mappings.
872 */ 872 */
873 if (1 + ra_want > map_blocks && 873 if (1 + ra_want > map_blocks &&
874 map_off < 874 map_off <
875 XFS_DIR2_BYTE_TO_DA(mp, XFS_DIR2_LEAF_OFFSET)) { 875 XFS_DIR2_BYTE_TO_DA(mp, XFS_DIR2_LEAF_OFFSET)) {
876 /* 876 /*
877 * Get more bmaps, fill in after the ones 877 * Get more bmaps, fill in after the ones
878 * we already have in the table. 878 * we already have in the table.
879 */ 879 */
880 nmap = map_size - map_valid; 880 nmap = map_size - map_valid;
881 error = xfs_bmapi(tp, dp, 881 error = xfs_bmapi(tp, dp,
882 map_off, 882 map_off,
883 XFS_DIR2_BYTE_TO_DA(mp, 883 XFS_DIR2_BYTE_TO_DA(mp,
884 XFS_DIR2_LEAF_OFFSET) - map_off, 884 XFS_DIR2_LEAF_OFFSET) - map_off,
885 XFS_BMAPI_METADATA, NULL, 0, 885 XFS_BMAPI_METADATA, NULL, 0,
886 &map[map_valid], &nmap, NULL); 886 &map[map_valid], &nmap, NULL);
887 /* 887 /*
888 * Don't know if we should ignore this or 888 * Don't know if we should ignore this or
889 * try to return an error. 889 * try to return an error.
890 * The trouble with returning errors 890 * The trouble with returning errors
891 * is that readdir will just stop without 891 * is that readdir will just stop without
892 * actually passing the error through. 892 * actually passing the error through.
893 */ 893 */
894 if (error) 894 if (error)
895 break; /* XXX */ 895 break; /* XXX */
896 /* 896 /*
897 * If we got all the mappings we asked for, 897 * If we got all the mappings we asked for,
898 * set the final map offset based on the 898 * set the final map offset based on the
899 * last bmap value received. 899 * last bmap value received.
900 * Otherwise, we've reached the end. 900 * Otherwise, we've reached the end.
901 */ 901 */
902 if (nmap == map_size - map_valid) 902 if (nmap == map_size - map_valid)
903 map_off = 903 map_off =
904 map[map_valid + nmap - 1].br_startoff + 904 map[map_valid + nmap - 1].br_startoff +
905 map[map_valid + nmap - 1].br_blockcount; 905 map[map_valid + nmap - 1].br_blockcount;
906 else 906 else
907 map_off = 907 map_off =
908 XFS_DIR2_BYTE_TO_DA(mp, 908 XFS_DIR2_BYTE_TO_DA(mp,
909 XFS_DIR2_LEAF_OFFSET); 909 XFS_DIR2_LEAF_OFFSET);
910 /* 910 /*
911 * Look for holes in the mapping, and 911 * Look for holes in the mapping, and
912 * eliminate them. Count up the valid blocks. 912 * eliminate them. Count up the valid blocks.
913 */ 913 */
914 for (i = map_valid; i < map_valid + nmap; ) { 914 for (i = map_valid; i < map_valid + nmap; ) {
915 if (map[i].br_startblock == 915 if (map[i].br_startblock ==
916 HOLESTARTBLOCK) { 916 HOLESTARTBLOCK) {
917 nmap--; 917 nmap--;
918 length = map_valid + nmap - i; 918 length = map_valid + nmap - i;
919 if (length) 919 if (length)
920 memmove(&map[i], 920 memmove(&map[i],
921 &map[i + 1], 921 &map[i + 1],
922 sizeof(map[i]) * 922 sizeof(map[i]) *
923 length); 923 length);
924 } else { 924 } else {
925 map_blocks += 925 map_blocks +=
926 map[i].br_blockcount; 926 map[i].br_blockcount;
927 i++; 927 i++;
928 } 928 }
929 } 929 }
930 map_valid += nmap; 930 map_valid += nmap;
931 } 931 }
932 /* 932 /*
933 * No valid mappings, so no more data blocks. 933 * No valid mappings, so no more data blocks.
934 */ 934 */
935 if (!map_valid) { 935 if (!map_valid) {
936 curoff = XFS_DIR2_DA_TO_BYTE(mp, map_off); 936 curoff = XFS_DIR2_DA_TO_BYTE(mp, map_off);
937 break; 937 break;
938 } 938 }
939 /* 939 /*
940 * Read the directory block starting at the first 940 * Read the directory block starting at the first
941 * mapping. 941 * mapping.
942 */ 942 */
943 curdb = XFS_DIR2_DA_TO_DB(mp, map->br_startoff); 943 curdb = XFS_DIR2_DA_TO_DB(mp, map->br_startoff);
944 error = xfs_da_read_buf(tp, dp, map->br_startoff, 944 error = xfs_da_read_buf(tp, dp, map->br_startoff,
945 map->br_blockcount >= mp->m_dirblkfsbs ? 945 map->br_blockcount >= mp->m_dirblkfsbs ?
946 XFS_FSB_TO_DADDR(mp, map->br_startblock) : 946 XFS_FSB_TO_DADDR(mp, map->br_startblock) :
947 -1, 947 -1,
948 &bp, XFS_DATA_FORK); 948 &bp, XFS_DATA_FORK);
949 /* 949 /*
950 * Should just skip over the data block instead 950 * Should just skip over the data block instead
951 * of giving up. 951 * of giving up.
952 */ 952 */
953 if (error) 953 if (error)
954 break; /* XXX */ 954 break; /* XXX */
955 /* 955 /*
956 * Adjust the current amount of read-ahead: we just 956 * Adjust the current amount of read-ahead: we just
957 * read a block that was previously ra. 957 * read a block that was previously ra.
958 */ 958 */
959 if (ra_current) 959 if (ra_current)
960 ra_current -= mp->m_dirblkfsbs; 960 ra_current -= mp->m_dirblkfsbs;
961 /* 961 /*
962 * Do we need more readahead? 962 * Do we need more readahead?
963 */ 963 */
964 for (ra_index = ra_offset = i = 0; 964 for (ra_index = ra_offset = i = 0;
965 ra_want > ra_current && i < map_blocks; 965 ra_want > ra_current && i < map_blocks;
966 i += mp->m_dirblkfsbs) { 966 i += mp->m_dirblkfsbs) {
967 ASSERT(ra_index < map_valid); 967 ASSERT(ra_index < map_valid);
968 /* 968 /*
969 * Read-ahead a contiguous directory block. 969 * Read-ahead a contiguous directory block.
970 */ 970 */
971 if (i > ra_current && 971 if (i > ra_current &&
972 map[ra_index].br_blockcount >= 972 map[ra_index].br_blockcount >=
973 mp->m_dirblkfsbs) { 973 mp->m_dirblkfsbs) {
974 xfs_baread(mp->m_ddev_targp, 974 xfs_baread(mp->m_ddev_targp,
975 XFS_FSB_TO_DADDR(mp, 975 XFS_FSB_TO_DADDR(mp,
976 map[ra_index].br_startblock + 976 map[ra_index].br_startblock +
977 ra_offset), 977 ra_offset),
978 (int)BTOBB(mp->m_dirblksize)); 978 (int)BTOBB(mp->m_dirblksize));
979 ra_current = i; 979 ra_current = i;
980 } 980 }
981 /* 981 /*
982 * Read-ahead a non-contiguous directory block. 982 * Read-ahead a non-contiguous directory block.
983 * This doesn't use our mapping, but this 983 * This doesn't use our mapping, but this
984 * is a very rare case. 984 * is a very rare case.
985 */ 985 */
986 else if (i > ra_current) { 986 else if (i > ra_current) {
987 (void)xfs_da_reada_buf(tp, dp, 987 (void)xfs_da_reada_buf(tp, dp,
988 map[ra_index].br_startoff + 988 map[ra_index].br_startoff +
989 ra_offset, XFS_DATA_FORK); 989 ra_offset, XFS_DATA_FORK);
990 ra_current = i; 990 ra_current = i;
991 } 991 }
992 /* 992 /*
993 * Advance offset through the mapping table. 993 * Advance offset through the mapping table.
994 */ 994 */
995 for (j = 0; j < mp->m_dirblkfsbs; j++) { 995 for (j = 0; j < mp->m_dirblkfsbs; j++) {
996 /* 996 /*
997 * The rest of this extent but not 997 * The rest of this extent but not
998 * more than a dir block. 998 * more than a dir block.
999 */ 999 */
1000 length = MIN(mp->m_dirblkfsbs, 1000 length = MIN(mp->m_dirblkfsbs,
1001 (int)(map[ra_index].br_blockcount - 1001 (int)(map[ra_index].br_blockcount -
1002 ra_offset)); 1002 ra_offset));
1003 j += length; 1003 j += length;
1004 ra_offset += length; 1004 ra_offset += length;
1005 /* 1005 /*
1006 * Advance to the next mapping if 1006 * Advance to the next mapping if
1007 * this one is used up. 1007 * this one is used up.
1008 */ 1008 */
1009 if (ra_offset == 1009 if (ra_offset ==
1010 map[ra_index].br_blockcount) { 1010 map[ra_index].br_blockcount) {
1011 ra_offset = 0; 1011 ra_offset = 0;
1012 ra_index++; 1012 ra_index++;
1013 } 1013 }
1014 } 1014 }
1015 } 1015 }
1016 /* 1016 /*
1017 * Having done a read, we need to set a new offset. 1017 * Having done a read, we need to set a new offset.
1018 */ 1018 */
1019 newoff = XFS_DIR2_DB_OFF_TO_BYTE(mp, curdb, 0); 1019 newoff = XFS_DIR2_DB_OFF_TO_BYTE(mp, curdb, 0);
1020 /* 1020 /*
1021 * Start of the current block. 1021 * Start of the current block.
1022 */ 1022 */
1023 if (curoff < newoff) 1023 if (curoff < newoff)
1024 curoff = newoff; 1024 curoff = newoff;
1025 /* 1025 /*
1026 * Make sure we're in the right block. 1026 * Make sure we're in the right block.
1027 */ 1027 */
1028 else if (curoff > newoff) 1028 else if (curoff > newoff)
1029 ASSERT(XFS_DIR2_BYTE_TO_DB(mp, curoff) == 1029 ASSERT(XFS_DIR2_BYTE_TO_DB(mp, curoff) ==
1030 curdb); 1030 curdb);
1031 data = bp->data; 1031 data = bp->data;
1032 xfs_dir2_data_check(dp, bp); 1032 xfs_dir2_data_check(dp, bp);
1033 /* 1033 /*
1034 * Find our position in the block. 1034 * Find our position in the block.
1035 */ 1035 */
1036 ptr = (char *)&data->u; 1036 ptr = (char *)&data->u;
1037 byteoff = XFS_DIR2_BYTE_TO_OFF(mp, curoff); 1037 byteoff = XFS_DIR2_BYTE_TO_OFF(mp, curoff);
1038 /* 1038 /*
1039 * Skip past the header. 1039 * Skip past the header.
1040 */ 1040 */
1041 if (byteoff == 0) 1041 if (byteoff == 0)
1042 curoff += (uint)sizeof(data->hdr); 1042 curoff += (uint)sizeof(data->hdr);
1043 /* 1043 /*
1044 * Skip past entries until we reach our offset. 1044 * Skip past entries until we reach our offset.
1045 */ 1045 */
1046 else { 1046 else {
1047 while ((char *)ptr - (char *)data < byteoff) { 1047 while ((char *)ptr - (char *)data < byteoff) {
1048 dup = (xfs_dir2_data_unused_t *)ptr; 1048 dup = (xfs_dir2_data_unused_t *)ptr;
1049 1049
1050 if (INT_GET(dup->freetag, ARCH_CONVERT) 1050 if (INT_GET(dup->freetag, ARCH_CONVERT)
1051 == XFS_DIR2_DATA_FREE_TAG) { 1051 == XFS_DIR2_DATA_FREE_TAG) {
1052 1052
1053 length = INT_GET(dup->length, 1053 length = INT_GET(dup->length,
1054 ARCH_CONVERT); 1054 ARCH_CONVERT);
1055 ptr += length; 1055 ptr += length;
1056 continue; 1056 continue;
1057 } 1057 }
1058 dep = (xfs_dir2_data_entry_t *)ptr; 1058 dep = (xfs_dir2_data_entry_t *)ptr;
1059 length = 1059 length =
1060 XFS_DIR2_DATA_ENTSIZE(dep->namelen); 1060 XFS_DIR2_DATA_ENTSIZE(dep->namelen);
1061 ptr += length; 1061 ptr += length;
1062 } 1062 }
1063 /* 1063 /*
1064 * Now set our real offset. 1064 * Now set our real offset.
1065 */ 1065 */
1066 curoff = 1066 curoff =
1067 XFS_DIR2_DB_OFF_TO_BYTE(mp, 1067 XFS_DIR2_DB_OFF_TO_BYTE(mp,
1068 XFS_DIR2_BYTE_TO_DB(mp, curoff), 1068 XFS_DIR2_BYTE_TO_DB(mp, curoff),
1069 (char *)ptr - (char *)data); 1069 (char *)ptr - (char *)data);
1070 if (ptr >= (char *)data + mp->m_dirblksize) { 1070 if (ptr >= (char *)data + mp->m_dirblksize) {
1071 continue; 1071 continue;
1072 } 1072 }
1073 } 1073 }
1074 } 1074 }
1075 /* 1075 /*
1076 * We have a pointer to an entry. 1076 * We have a pointer to an entry.
1077 * Is it a live one? 1077 * Is it a live one?
1078 */ 1078 */
1079 dup = (xfs_dir2_data_unused_t *)ptr; 1079 dup = (xfs_dir2_data_unused_t *)ptr;
1080 /* 1080 /*
1081 * No, it's unused, skip over it. 1081 * No, it's unused, skip over it.
1082 */ 1082 */
1083 if (INT_GET(dup->freetag, ARCH_CONVERT) 1083 if (INT_GET(dup->freetag, ARCH_CONVERT)
1084 == XFS_DIR2_DATA_FREE_TAG) { 1084 == XFS_DIR2_DATA_FREE_TAG) {
1085 length = INT_GET(dup->length, ARCH_CONVERT); 1085 length = INT_GET(dup->length, ARCH_CONVERT);
1086 ptr += length; 1086 ptr += length;
1087 curoff += length; 1087 curoff += length;
1088 continue; 1088 continue;
1089 } 1089 }
1090 1090
1091 /* 1091 /*
1092 * Copy the entry into the putargs, and try formatting it. 1092 * Copy the entry into the putargs, and try formatting it.
1093 */ 1093 */
1094 dep = (xfs_dir2_data_entry_t *)ptr; 1094 dep = (xfs_dir2_data_entry_t *)ptr;
1095 1095
1096 p->namelen = dep->namelen; 1096 p->namelen = dep->namelen;
1097 1097
1098 length = XFS_DIR2_DATA_ENTSIZE(p->namelen); 1098 length = XFS_DIR2_DATA_ENTSIZE(p->namelen);
1099 1099
1100 p->cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length); 1100 p->cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length);
1101 1101
1102 p->ino = INT_GET(dep->inumber, ARCH_CONVERT); 1102 p->ino = INT_GET(dep->inumber, ARCH_CONVERT);
1103 #if XFS_BIG_INUMS 1103 #if XFS_BIG_INUMS
1104 p->ino += mp->m_inoadd; 1104 p->ino += mp->m_inoadd;
1105 #endif 1105 #endif
1106 p->name = (char *)dep->name; 1106 p->name = (char *)dep->name;
1107 1107
1108 error = p->put(p); 1108 error = p->put(p);
1109 1109
1110 /* 1110 /*
1111 * Won't fit. Return to caller. 1111 * Won't fit. Return to caller.
1112 */ 1112 */
1113 if (!p->done) { 1113 if (!p->done) {
1114 eof = 0; 1114 eof = 0;
1115 break; 1115 break;
1116 } 1116 }
1117 /* 1117 /*
1118 * Advance to next entry in the block. 1118 * Advance to next entry in the block.
1119 */ 1119 */
1120 ptr += length; 1120 ptr += length;
1121 curoff += length; 1121 curoff += length;
1122 } 1122 }
1123 1123
1124 /* 1124 /*
1125 * All done. Set output offset value to current offset. 1125 * All done. Set output offset value to current offset.
1126 */ 1126 */
1127 *eofp = eof; 1127 *eofp = eof;
1128 if (curoff > XFS_DIR2_DATAPTR_TO_BYTE(mp, XFS_DIR2_MAX_DATAPTR)) 1128 if (curoff > XFS_DIR2_DATAPTR_TO_BYTE(mp, XFS_DIR2_MAX_DATAPTR))
1129 uio->uio_offset = XFS_DIR2_MAX_DATAPTR; 1129 uio->uio_offset = XFS_DIR2_MAX_DATAPTR;
1130 else 1130 else
1131 uio->uio_offset = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff); 1131 uio->uio_offset = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff);
1132 kmem_free(map, map_size * sizeof(*map)); 1132 kmem_free(map, map_size * sizeof(*map));
1133 kmem_free(p, sizeof(*p)); 1133 kmem_free(p, sizeof(*p));
1134 if (bp) 1134 if (bp)
1135 xfs_da_brelse(tp, bp); 1135 xfs_da_brelse(tp, bp);
1136 return error; 1136 return error;
1137 } 1137 }
1138 1138
1139 /* 1139 /*
1140 * Initialize a new leaf block, leaf1 or leafn magic accepted. 1140 * Initialize a new leaf block, leaf1 or leafn magic accepted.
1141 */ 1141 */
1142 int 1142 int
1143 xfs_dir2_leaf_init( 1143 xfs_dir2_leaf_init(
1144 xfs_da_args_t *args, /* operation arguments */ 1144 xfs_da_args_t *args, /* operation arguments */
1145 xfs_dir2_db_t bno, /* directory block number */ 1145 xfs_dir2_db_t bno, /* directory block number */
1146 xfs_dabuf_t **bpp, /* out: leaf buffer */ 1146 xfs_dabuf_t **bpp, /* out: leaf buffer */
1147 int magic) /* magic number for block */ 1147 int magic) /* magic number for block */
1148 { 1148 {
1149 xfs_dabuf_t *bp; /* leaf buffer */ 1149 xfs_dabuf_t *bp; /* leaf buffer */
1150 xfs_inode_t *dp; /* incore directory inode */ 1150 xfs_inode_t *dp; /* incore directory inode */
1151 int error; /* error return code */ 1151 int error; /* error return code */
1152 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1152 xfs_dir2_leaf_t *leaf; /* leaf structure */
1153 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 1153 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
1154 xfs_mount_t *mp; /* filesystem mount point */ 1154 xfs_mount_t *mp; /* filesystem mount point */
1155 xfs_trans_t *tp; /* transaction pointer */ 1155 xfs_trans_t *tp; /* transaction pointer */
1156 1156
1157 dp = args->dp; 1157 dp = args->dp;
1158 ASSERT(dp != NULL); 1158 ASSERT(dp != NULL);
1159 tp = args->trans; 1159 tp = args->trans;
1160 mp = dp->i_mount; 1160 mp = dp->i_mount;
1161 ASSERT(bno >= XFS_DIR2_LEAF_FIRSTDB(mp) && 1161 ASSERT(bno >= XFS_DIR2_LEAF_FIRSTDB(mp) &&
1162 bno < XFS_DIR2_FREE_FIRSTDB(mp)); 1162 bno < XFS_DIR2_FREE_FIRSTDB(mp));
1163 /* 1163 /*
1164 * Get the buffer for the block. 1164 * Get the buffer for the block.
1165 */ 1165 */
1166 error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, bno), -1, &bp, 1166 error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, bno), -1, &bp,
1167 XFS_DATA_FORK); 1167 XFS_DATA_FORK);
1168 if (error) { 1168 if (error) {
1169 return error; 1169 return error;
1170 } 1170 }
1171 ASSERT(bp != NULL); 1171 ASSERT(bp != NULL);
1172 leaf = bp->data; 1172 leaf = bp->data;
1173 /* 1173 /*
1174 * Initialize the header. 1174 * Initialize the header.
1175 */ 1175 */
1176 INT_SET(leaf->hdr.info.magic, ARCH_CONVERT, magic); 1176 INT_SET(leaf->hdr.info.magic, ARCH_CONVERT, magic);
1177 leaf->hdr.info.forw = 0; 1177 leaf->hdr.info.forw = 0;
1178 leaf->hdr.info.back = 0; 1178 leaf->hdr.info.back = 0;
1179 leaf->hdr.count = 0; 1179 leaf->hdr.count = 0;
1180 leaf->hdr.stale = 0; 1180 leaf->hdr.stale = 0;
1181 xfs_dir2_leaf_log_header(tp, bp); 1181 xfs_dir2_leaf_log_header(tp, bp);
1182 /* 1182 /*
1183 * If it's a leaf-format directory initialize the tail. 1183 * If it's a leaf-format directory initialize the tail.
1184 * In this case our caller has the real bests table to copy into 1184 * In this case our caller has the real bests table to copy into
1185 * the block. 1185 * the block.
1186 */ 1186 */
1187 if (magic == XFS_DIR2_LEAF1_MAGIC) { 1187 if (magic == XFS_DIR2_LEAF1_MAGIC) {
1188 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); 1188 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
1189 ltp->bestcount = 0; 1189 ltp->bestcount = 0;
1190 xfs_dir2_leaf_log_tail(tp, bp); 1190 xfs_dir2_leaf_log_tail(tp, bp);
1191 } 1191 }
1192 *bpp = bp; 1192 *bpp = bp;
1193 return 0; 1193 return 0;
1194 } 1194 }
1195 1195
1196 /* 1196 /*
1197 * Log the bests entries indicated from a leaf1 block. 1197 * Log the bests entries indicated from a leaf1 block.
1198 */ 1198 */
1199 static void 1199 static void
1200 xfs_dir2_leaf_log_bests( 1200 xfs_dir2_leaf_log_bests(
1201 xfs_trans_t *tp, /* transaction pointer */ 1201 xfs_trans_t *tp, /* transaction pointer */
1202 xfs_dabuf_t *bp, /* leaf buffer */ 1202 xfs_dabuf_t *bp, /* leaf buffer */
1203 int first, /* first entry to log */ 1203 int first, /* first entry to log */
1204 int last) /* last entry to log */ 1204 int last) /* last entry to log */
1205 { 1205 {
1206 xfs_dir2_data_off_t *firstb; /* pointer to first entry */ 1206 xfs_dir2_data_off_t *firstb; /* pointer to first entry */
1207 xfs_dir2_data_off_t *lastb; /* pointer to last entry */ 1207 xfs_dir2_data_off_t *lastb; /* pointer to last entry */
1208 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1208 xfs_dir2_leaf_t *leaf; /* leaf structure */
1209 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 1209 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
1210 1210
1211 leaf = bp->data; 1211 leaf = bp->data;
1212 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC); 1212 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC);
1213 ltp = XFS_DIR2_LEAF_TAIL_P(tp->t_mountp, leaf); 1213 ltp = XFS_DIR2_LEAF_TAIL_P(tp->t_mountp, leaf);
1214 firstb = XFS_DIR2_LEAF_BESTS_P(ltp) + first; 1214 firstb = XFS_DIR2_LEAF_BESTS_P(ltp) + first;
1215 lastb = XFS_DIR2_LEAF_BESTS_P(ltp) + last; 1215 lastb = XFS_DIR2_LEAF_BESTS_P(ltp) + last;
1216 xfs_da_log_buf(tp, bp, (uint)((char *)firstb - (char *)leaf), 1216 xfs_da_log_buf(tp, bp, (uint)((char *)firstb - (char *)leaf),
1217 (uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1)); 1217 (uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1));
1218 } 1218 }
1219 1219
1220 /* 1220 /*
1221 * Log the leaf entries indicated from a leaf1 or leafn block. 1221 * Log the leaf entries indicated from a leaf1 or leafn block.
1222 */ 1222 */
1223 void 1223 void
1224 xfs_dir2_leaf_log_ents( 1224 xfs_dir2_leaf_log_ents(
1225 xfs_trans_t *tp, /* transaction pointer */ 1225 xfs_trans_t *tp, /* transaction pointer */
1226 xfs_dabuf_t *bp, /* leaf buffer */ 1226 xfs_dabuf_t *bp, /* leaf buffer */
1227 int first, /* first entry to log */ 1227 int first, /* first entry to log */
1228 int last) /* last entry to log */ 1228 int last) /* last entry to log */
1229 { 1229 {
1230 xfs_dir2_leaf_entry_t *firstlep; /* pointer to first entry */ 1230 xfs_dir2_leaf_entry_t *firstlep; /* pointer to first entry */
1231 xfs_dir2_leaf_entry_t *lastlep; /* pointer to last entry */ 1231 xfs_dir2_leaf_entry_t *lastlep; /* pointer to last entry */
1232 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1232 xfs_dir2_leaf_t *leaf; /* leaf structure */
1233 1233
1234 leaf = bp->data; 1234 leaf = bp->data;
1235 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC || 1235 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC ||
1236 INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); 1236 INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
1237 firstlep = &leaf->ents[first]; 1237 firstlep = &leaf->ents[first];
1238 lastlep = &leaf->ents[last]; 1238 lastlep = &leaf->ents[last];
1239 xfs_da_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf), 1239 xfs_da_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf),
1240 (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1)); 1240 (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1));
1241 } 1241 }
1242 1242
1243 /* 1243 /*
1244 * Log the header of the leaf1 or leafn block. 1244 * Log the header of the leaf1 or leafn block.
1245 */ 1245 */
1246 void 1246 void
1247 xfs_dir2_leaf_log_header( 1247 xfs_dir2_leaf_log_header(
1248 xfs_trans_t *tp, /* transaction pointer */ 1248 xfs_trans_t *tp, /* transaction pointer */
1249 xfs_dabuf_t *bp) /* leaf buffer */ 1249 xfs_dabuf_t *bp) /* leaf buffer */
1250 { 1250 {
1251 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1251 xfs_dir2_leaf_t *leaf; /* leaf structure */
1252 1252
1253 leaf = bp->data; 1253 leaf = bp->data;
1254 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC || 1254 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC ||
1255 INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); 1255 INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
1256 xfs_da_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf), 1256 xfs_da_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf),
1257 (uint)(sizeof(leaf->hdr) - 1)); 1257 (uint)(sizeof(leaf->hdr) - 1));
1258 } 1258 }
1259 1259
1260 /* 1260 /*
1261 * Log the tail of the leaf1 block. 1261 * Log the tail of the leaf1 block.
1262 */ 1262 */
1263 STATIC void 1263 STATIC void
1264 xfs_dir2_leaf_log_tail( 1264 xfs_dir2_leaf_log_tail(
1265 xfs_trans_t *tp, /* transaction pointer */ 1265 xfs_trans_t *tp, /* transaction pointer */
1266 xfs_dabuf_t *bp) /* leaf buffer */ 1266 xfs_dabuf_t *bp) /* leaf buffer */
1267 { 1267 {
1268 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1268 xfs_dir2_leaf_t *leaf; /* leaf structure */
1269 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 1269 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
1270 xfs_mount_t *mp; /* filesystem mount point */ 1270 xfs_mount_t *mp; /* filesystem mount point */
1271 1271
1272 mp = tp->t_mountp; 1272 mp = tp->t_mountp;
1273 leaf = bp->data; 1273 leaf = bp->data;
1274 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC); 1274 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC);
1275 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); 1275 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
1276 xfs_da_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf), 1276 xfs_da_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf),
1277 (uint)(mp->m_dirblksize - 1)); 1277 (uint)(mp->m_dirblksize - 1));
1278 } 1278 }
1279 1279
1280 /* 1280 /*
1281 * Look up the entry referred to by args in the leaf format directory. 1281 * Look up the entry referred to by args in the leaf format directory.
1282 * Most of the work is done by the xfs_dir2_leaf_lookup_int routine which 1282 * Most of the work is done by the xfs_dir2_leaf_lookup_int routine which
1283 * is also used by the node-format code. 1283 * is also used by the node-format code.
1284 */ 1284 */
1285 int 1285 int
1286 xfs_dir2_leaf_lookup( 1286 xfs_dir2_leaf_lookup(
1287 xfs_da_args_t *args) /* operation arguments */ 1287 xfs_da_args_t *args) /* operation arguments */
1288 { 1288 {
1289 xfs_dabuf_t *dbp; /* data block buffer */ 1289 xfs_dabuf_t *dbp; /* data block buffer */
1290 xfs_dir2_data_entry_t *dep; /* data block entry */ 1290 xfs_dir2_data_entry_t *dep; /* data block entry */
1291 xfs_inode_t *dp; /* incore directory inode */ 1291 xfs_inode_t *dp; /* incore directory inode */
1292 int error; /* error return code */ 1292 int error; /* error return code */
1293 int index; /* found entry index */ 1293 int index; /* found entry index */
1294 xfs_dabuf_t *lbp; /* leaf buffer */ 1294 xfs_dabuf_t *lbp; /* leaf buffer */
1295 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1295 xfs_dir2_leaf_t *leaf; /* leaf structure */
1296 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 1296 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
1297 xfs_trans_t *tp; /* transaction pointer */ 1297 xfs_trans_t *tp; /* transaction pointer */
1298 1298
1299 xfs_dir2_trace_args("leaf_lookup", args); 1299 xfs_dir2_trace_args("leaf_lookup", args);
1300 /* 1300 /*
1301 * Look up name in the leaf block, returning both buffers and index. 1301 * Look up name in the leaf block, returning both buffers and index.
1302 */ 1302 */
1303 if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { 1303 if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) {
1304 return error; 1304 return error;
1305 } 1305 }
1306 tp = args->trans; 1306 tp = args->trans;
1307 dp = args->dp; 1307 dp = args->dp;
1308 xfs_dir2_leaf_check(dp, lbp); 1308 xfs_dir2_leaf_check(dp, lbp);
1309 leaf = lbp->data; 1309 leaf = lbp->data;
1310 /* 1310 /*
1311 * Get to the leaf entry and contained data entry address. 1311 * Get to the leaf entry and contained data entry address.
1312 */ 1312 */
1313 lep = &leaf->ents[index]; 1313 lep = &leaf->ents[index];
1314 /* 1314 /*
1315 * Point to the data entry. 1315 * Point to the data entry.
1316 */ 1316 */
1317 dep = (xfs_dir2_data_entry_t *) 1317 dep = (xfs_dir2_data_entry_t *)
1318 ((char *)dbp->data + 1318 ((char *)dbp->data +
1319 XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, INT_GET(lep->address, ARCH_CONVERT))); 1319 XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, INT_GET(lep->address, ARCH_CONVERT)));
1320 /* 1320 /*
1321 * Return the found inode number. 1321 * Return the found inode number.
1322 */ 1322 */
1323 args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); 1323 args->inumber = INT_GET(dep->inumber, ARCH_CONVERT);
1324 xfs_da_brelse(tp, dbp); 1324 xfs_da_brelse(tp, dbp);
1325 xfs_da_brelse(tp, lbp); 1325 xfs_da_brelse(tp, lbp);
1326 return XFS_ERROR(EEXIST); 1326 return XFS_ERROR(EEXIST);
1327 } 1327 }
1328 1328
1329 /* 1329 /*
1330 * Look up name/hash in the leaf block. 1330 * Look up name/hash in the leaf block.
1331 * Fill in indexp with the found index, and dbpp with the data buffer. 1331 * Fill in indexp with the found index, and dbpp with the data buffer.
1332 * If not found dbpp will be NULL, and ENOENT comes back. 1332 * If not found dbpp will be NULL, and ENOENT comes back.
1333 * lbpp will always be filled in with the leaf buffer unless there's an error. 1333 * lbpp will always be filled in with the leaf buffer unless there's an error.
1334 */ 1334 */
1335 static int /* error */ 1335 static int /* error */
1336 xfs_dir2_leaf_lookup_int( 1336 xfs_dir2_leaf_lookup_int(
1337 xfs_da_args_t *args, /* operation arguments */ 1337 xfs_da_args_t *args, /* operation arguments */
1338 xfs_dabuf_t **lbpp, /* out: leaf buffer */ 1338 xfs_dabuf_t **lbpp, /* out: leaf buffer */
1339 int *indexp, /* out: index in leaf block */ 1339 int *indexp, /* out: index in leaf block */
1340 xfs_dabuf_t **dbpp) /* out: data buffer */ 1340 xfs_dabuf_t **dbpp) /* out: data buffer */
1341 { 1341 {
1342 xfs_dir2_db_t curdb; /* current data block number */ 1342 xfs_dir2_db_t curdb; /* current data block number */
1343 xfs_dabuf_t *dbp; /* data buffer */ 1343 xfs_dabuf_t *dbp; /* data buffer */
1344 xfs_dir2_data_entry_t *dep; /* data entry */ 1344 xfs_dir2_data_entry_t *dep; /* data entry */
1345 xfs_inode_t *dp; /* incore directory inode */ 1345 xfs_inode_t *dp; /* incore directory inode */
1346 int error; /* error return code */ 1346 int error; /* error return code */
1347 int index; /* index in leaf block */ 1347 int index; /* index in leaf block */
1348 xfs_dabuf_t *lbp; /* leaf buffer */ 1348 xfs_dabuf_t *lbp; /* leaf buffer */
1349 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 1349 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
1350 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1350 xfs_dir2_leaf_t *leaf; /* leaf structure */
1351 xfs_mount_t *mp; /* filesystem mount point */ 1351 xfs_mount_t *mp; /* filesystem mount point */
1352 xfs_dir2_db_t newdb; /* new data block number */ 1352 xfs_dir2_db_t newdb; /* new data block number */
1353 xfs_trans_t *tp; /* transaction pointer */ 1353 xfs_trans_t *tp; /* transaction pointer */
1354 1354
1355 dp = args->dp; 1355 dp = args->dp;
1356 tp = args->trans; 1356 tp = args->trans;
1357 mp = dp->i_mount; 1357 mp = dp->i_mount;
1358 /* 1358 /*
1359 * Read the leaf block into the buffer. 1359 * Read the leaf block into the buffer.
1360 */ 1360 */
1361 if ((error = 1361 if ((error =
1362 xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp, 1362 xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp,
1363 XFS_DATA_FORK))) { 1363 XFS_DATA_FORK))) {
1364 return error; 1364 return error;
1365 } 1365 }
1366 *lbpp = lbp; 1366 *lbpp = lbp;
1367 leaf = lbp->data; 1367 leaf = lbp->data;
1368 xfs_dir2_leaf_check(dp, lbp); 1368 xfs_dir2_leaf_check(dp, lbp);
1369 /* 1369 /*
1370 * Look for the first leaf entry with our hash value. 1370 * Look for the first leaf entry with our hash value.
1371 */ 1371 */
1372 index = xfs_dir2_leaf_search_hash(args, lbp); 1372 index = xfs_dir2_leaf_search_hash(args, lbp);
1373 /* 1373 /*
1374 * Loop over all the entries with the right hash value 1374 * Loop over all the entries with the right hash value
1375 * looking to match the name. 1375 * looking to match the name.
1376 */ 1376 */
1377 for (lep = &leaf->ents[index], dbp = NULL, curdb = -1; 1377 for (lep = &leaf->ents[index], dbp = NULL, curdb = -1;
1378 index < INT_GET(leaf->hdr.count, ARCH_CONVERT) && INT_GET(lep->hashval, ARCH_CONVERT) == args->hashval; 1378 index < INT_GET(leaf->hdr.count, ARCH_CONVERT) && INT_GET(lep->hashval, ARCH_CONVERT) == args->hashval;
1379 lep++, index++) { 1379 lep++, index++) {
1380 /* 1380 /*
1381 * Skip over stale leaf entries. 1381 * Skip over stale leaf entries.
1382 */ 1382 */
1383 if (INT_GET(lep->address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) 1383 if (INT_GET(lep->address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
1384 continue; 1384 continue;
1385 /* 1385 /*
1386 * Get the new data block number. 1386 * Get the new data block number.
1387 */ 1387 */
1388 newdb = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT)); 1388 newdb = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT));
1389 /* 1389 /*
1390 * If it's not the same as the old data block number, 1390 * If it's not the same as the old data block number,
1391 * need to pitch the old one and read the new one. 1391 * need to pitch the old one and read the new one.
1392 */ 1392 */
1393 if (newdb != curdb) { 1393 if (newdb != curdb) {
1394 if (dbp) 1394 if (dbp)
1395 xfs_da_brelse(tp, dbp); 1395 xfs_da_brelse(tp, dbp);
1396 if ((error = 1396 if ((error =
1397 xfs_da_read_buf(tp, dp, 1397 xfs_da_read_buf(tp, dp,
1398 XFS_DIR2_DB_TO_DA(mp, newdb), -1, &dbp, 1398 XFS_DIR2_DB_TO_DA(mp, newdb), -1, &dbp,
1399 XFS_DATA_FORK))) { 1399 XFS_DATA_FORK))) {
1400 xfs_da_brelse(tp, lbp); 1400 xfs_da_brelse(tp, lbp);
1401 return error; 1401 return error;
1402 } 1402 }
1403 xfs_dir2_data_check(dp, dbp); 1403 xfs_dir2_data_check(dp, dbp);
1404 curdb = newdb; 1404 curdb = newdb;
1405 } 1405 }
1406 /* 1406 /*
1407 * Point to the data entry. 1407 * Point to the data entry.
1408 */ 1408 */
1409 dep = (xfs_dir2_data_entry_t *) 1409 dep = (xfs_dir2_data_entry_t *)
1410 ((char *)dbp->data + 1410 ((char *)dbp->data +
1411 XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(lep->address, ARCH_CONVERT))); 1411 XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(lep->address, ARCH_CONVERT)));
1412 /* 1412 /*
1413 * If it matches then return it. 1413 * If it matches then return it.
1414 */ 1414 */
1415 if (dep->namelen == args->namelen && 1415 if (dep->namelen == args->namelen &&
1416 dep->name[0] == args->name[0] && 1416 dep->name[0] == args->name[0] &&
1417 memcmp(dep->name, args->name, args->namelen) == 0) { 1417 memcmp(dep->name, args->name, args->namelen) == 0) {
1418 *dbpp = dbp; 1418 *dbpp = dbp;
1419 *indexp = index; 1419 *indexp = index;
1420 return 0; 1420 return 0;
1421 } 1421 }
1422 } 1422 }
1423 /* 1423 /*
1424 * No match found, return ENOENT. 1424 * No match found, return ENOENT.
1425 */ 1425 */
1426 ASSERT(args->oknoent); 1426 ASSERT(args->oknoent);
1427 if (dbp) 1427 if (dbp)
1428 xfs_da_brelse(tp, dbp); 1428 xfs_da_brelse(tp, dbp);
1429 xfs_da_brelse(tp, lbp); 1429 xfs_da_brelse(tp, lbp);
1430 return XFS_ERROR(ENOENT); 1430 return XFS_ERROR(ENOENT);
1431 } 1431 }
1432 1432
1433 /* 1433 /*
1434 * Remove an entry from a leaf format directory. 1434 * Remove an entry from a leaf format directory.
1435 */ 1435 */
1436 int /* error */ 1436 int /* error */
1437 xfs_dir2_leaf_removename( 1437 xfs_dir2_leaf_removename(
1438 xfs_da_args_t *args) /* operation arguments */ 1438 xfs_da_args_t *args) /* operation arguments */
1439 { 1439 {
1440 xfs_dir2_data_off_t *bestsp; /* leaf block best freespace */ 1440 xfs_dir2_data_off_t *bestsp; /* leaf block best freespace */
1441 xfs_dir2_data_t *data; /* data block structure */ 1441 xfs_dir2_data_t *data; /* data block structure */
1442 xfs_dir2_db_t db; /* data block number */ 1442 xfs_dir2_db_t db; /* data block number */
1443 xfs_dabuf_t *dbp; /* data block buffer */ 1443 xfs_dabuf_t *dbp; /* data block buffer */
1444 xfs_dir2_data_entry_t *dep; /* data entry structure */ 1444 xfs_dir2_data_entry_t *dep; /* data entry structure */
1445 xfs_inode_t *dp; /* incore directory inode */ 1445 xfs_inode_t *dp; /* incore directory inode */
1446 int error; /* error return code */ 1446 int error; /* error return code */
1447 xfs_dir2_db_t i; /* temporary data block # */ 1447 xfs_dir2_db_t i; /* temporary data block # */
1448 int index; /* index into leaf entries */ 1448 int index; /* index into leaf entries */
1449 xfs_dabuf_t *lbp; /* leaf buffer */ 1449 xfs_dabuf_t *lbp; /* leaf buffer */
1450 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1450 xfs_dir2_leaf_t *leaf; /* leaf structure */
1451 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 1451 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
1452 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 1452 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
1453 xfs_mount_t *mp; /* filesystem mount point */ 1453 xfs_mount_t *mp; /* filesystem mount point */
1454 int needlog; /* need to log data header */ 1454 int needlog; /* need to log data header */
1455 int needscan; /* need to rescan data frees */ 1455 int needscan; /* need to rescan data frees */
1456 xfs_dir2_data_off_t oldbest; /* old value of best free */ 1456 xfs_dir2_data_off_t oldbest; /* old value of best free */
1457 xfs_trans_t *tp; /* transaction pointer */ 1457 xfs_trans_t *tp; /* transaction pointer */
1458 1458
1459 xfs_dir2_trace_args("leaf_removename", args); 1459 xfs_dir2_trace_args("leaf_removename", args);
1460 /* 1460 /*
1461 * Lookup the leaf entry, get the leaf and data blocks read in. 1461 * Lookup the leaf entry, get the leaf and data blocks read in.
1462 */ 1462 */
1463 if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { 1463 if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) {
1464 return error; 1464 return error;
1465 } 1465 }
1466 dp = args->dp; 1466 dp = args->dp;
1467 tp = args->trans; 1467 tp = args->trans;
1468 mp = dp->i_mount; 1468 mp = dp->i_mount;
1469 leaf = lbp->data; 1469 leaf = lbp->data;
1470 data = dbp->data; 1470 data = dbp->data;
1471 xfs_dir2_data_check(dp, dbp); 1471 xfs_dir2_data_check(dp, dbp);
1472 /* 1472 /*
1473 * Point to the leaf entry, use that to point to the data entry. 1473 * Point to the leaf entry, use that to point to the data entry.
1474 */ 1474 */
1475 lep = &leaf->ents[index]; 1475 lep = &leaf->ents[index];
1476 db = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT)); 1476 db = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT));
1477 dep = (xfs_dir2_data_entry_t *) 1477 dep = (xfs_dir2_data_entry_t *)
1478 ((char *)data + XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(lep->address, ARCH_CONVERT))); 1478 ((char *)data + XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(lep->address, ARCH_CONVERT)));
1479 needscan = needlog = 0; 1479 needscan = needlog = 0;
1480 oldbest = INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT); 1480 oldbest = be16_to_cpu(data->hdr.bestfree[0].length);
1481 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); 1481 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
1482 bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); 1482 bestsp = XFS_DIR2_LEAF_BESTS_P(ltp);
1483 ASSERT(INT_GET(bestsp[db], ARCH_CONVERT) == oldbest); 1483 ASSERT(INT_GET(bestsp[db], ARCH_CONVERT) == oldbest);
1484 /* 1484 /*
1485 * Mark the former data entry unused. 1485 * Mark the former data entry unused.
1486 */ 1486 */
1487 xfs_dir2_data_make_free(tp, dbp, 1487 xfs_dir2_data_make_free(tp, dbp,
1488 (xfs_dir2_data_aoff_t)((char *)dep - (char *)data), 1488 (xfs_dir2_data_aoff_t)((char *)dep - (char *)data),
1489 XFS_DIR2_DATA_ENTSIZE(dep->namelen), &needlog, &needscan); 1489 XFS_DIR2_DATA_ENTSIZE(dep->namelen), &needlog, &needscan);
1490 /* 1490 /*
1491 * We just mark the leaf entry stale by putting a null in it. 1491 * We just mark the leaf entry stale by putting a null in it.
1492 */ 1492 */
1493 INT_MOD(leaf->hdr.stale, ARCH_CONVERT, +1); 1493 INT_MOD(leaf->hdr.stale, ARCH_CONVERT, +1);
1494 xfs_dir2_leaf_log_header(tp, lbp); 1494 xfs_dir2_leaf_log_header(tp, lbp);
1495 INT_SET(lep->address, ARCH_CONVERT, XFS_DIR2_NULL_DATAPTR); 1495 INT_SET(lep->address, ARCH_CONVERT, XFS_DIR2_NULL_DATAPTR);
1496 xfs_dir2_leaf_log_ents(tp, lbp, index, index); 1496 xfs_dir2_leaf_log_ents(tp, lbp, index, index);
1497 /* 1497 /*
1498 * Scan the freespace in the data block again if necessary, 1498 * Scan the freespace in the data block again if necessary,
1499 * log the data block header if necessary. 1499 * log the data block header if necessary.
1500 */ 1500 */
1501 if (needscan) 1501 if (needscan)
1502 xfs_dir2_data_freescan(mp, data, &needlog, NULL); 1502 xfs_dir2_data_freescan(mp, data, &needlog, NULL);
1503 if (needlog) 1503 if (needlog)
1504 xfs_dir2_data_log_header(tp, dbp); 1504 xfs_dir2_data_log_header(tp, dbp);
1505 /* 1505 /*
1506 * If the longest freespace in the data block has changed, 1506 * If the longest freespace in the data block has changed,
1507 * put the new value in the bests table and log that. 1507 * put the new value in the bests table and log that.
1508 */ 1508 */
1509 if (INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT) != oldbest) { 1509 if (be16_to_cpu(data->hdr.bestfree[0].length) != oldbest) {
1510 INT_COPY(bestsp[db], data->hdr.bestfree[0].length, ARCH_CONVERT); 1510 bestsp[db] = data->hdr.bestfree[0].length;
1511 xfs_dir2_leaf_log_bests(tp, lbp, db, db); 1511 xfs_dir2_leaf_log_bests(tp, lbp, db, db);
1512 } 1512 }
1513 xfs_dir2_data_check(dp, dbp); 1513 xfs_dir2_data_check(dp, dbp);
1514 /* 1514 /*
1515 * If the data block is now empty then get rid of the data block. 1515 * If the data block is now empty then get rid of the data block.
1516 */ 1516 */
1517 if (INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT) == 1517 if (be16_to_cpu(data->hdr.bestfree[0].length) ==
1518 mp->m_dirblksize - (uint)sizeof(data->hdr)) { 1518 mp->m_dirblksize - (uint)sizeof(data->hdr)) {
1519 ASSERT(db != mp->m_dirdatablk); 1519 ASSERT(db != mp->m_dirdatablk);
1520 if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { 1520 if ((error = xfs_dir2_shrink_inode(args, db, dbp))) {
1521 /* 1521 /*
1522 * Nope, can't get rid of it because it caused 1522 * Nope, can't get rid of it because it caused
1523 * allocation of a bmap btree block to do so. 1523 * allocation of a bmap btree block to do so.
1524 * Just go on, returning success, leaving the 1524 * Just go on, returning success, leaving the
1525 * empty block in place. 1525 * empty block in place.
1526 */ 1526 */
1527 if (error == ENOSPC && args->total == 0) { 1527 if (error == ENOSPC && args->total == 0) {
1528 xfs_da_buf_done(dbp); 1528 xfs_da_buf_done(dbp);
1529 error = 0; 1529 error = 0;
1530 } 1530 }
1531 xfs_dir2_leaf_check(dp, lbp); 1531 xfs_dir2_leaf_check(dp, lbp);
1532 xfs_da_buf_done(lbp); 1532 xfs_da_buf_done(lbp);
1533 return error; 1533 return error;
1534 } 1534 }
1535 dbp = NULL; 1535 dbp = NULL;
1536 /* 1536 /*
1537 * If this is the last data block then compact the 1537 * If this is the last data block then compact the
1538 * bests table by getting rid of entries. 1538 * bests table by getting rid of entries.
1539 */ 1539 */
1540 if (db == INT_GET(ltp->bestcount, ARCH_CONVERT) - 1) { 1540 if (db == INT_GET(ltp->bestcount, ARCH_CONVERT) - 1) {
1541 /* 1541 /*
1542 * Look for the last active entry (i). 1542 * Look for the last active entry (i).
1543 */ 1543 */
1544 for (i = db - 1; i > 0; i--) { 1544 for (i = db - 1; i > 0; i--) {
1545 if (INT_GET(bestsp[i], ARCH_CONVERT) != NULLDATAOFF) 1545 if (INT_GET(bestsp[i], ARCH_CONVERT) != NULLDATAOFF)
1546 break; 1546 break;
1547 } 1547 }
1548 /* 1548 /*
1549 * Copy the table down so inactive entries at the 1549 * Copy the table down so inactive entries at the
1550 * end are removed. 1550 * end are removed.
1551 */ 1551 */
1552 memmove(&bestsp[db - i], bestsp, 1552 memmove(&bestsp[db - i], bestsp,
1553 (INT_GET(ltp->bestcount, ARCH_CONVERT) - (db - i)) * sizeof(*bestsp)); 1553 (INT_GET(ltp->bestcount, ARCH_CONVERT) - (db - i)) * sizeof(*bestsp));
1554 INT_MOD(ltp->bestcount, ARCH_CONVERT, -(db - i)); 1554 INT_MOD(ltp->bestcount, ARCH_CONVERT, -(db - i));
1555 xfs_dir2_leaf_log_tail(tp, lbp); 1555 xfs_dir2_leaf_log_tail(tp, lbp);
1556 xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1); 1556 xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1);
1557 } else 1557 } else
1558 INT_SET(bestsp[db], ARCH_CONVERT, NULLDATAOFF); 1558 INT_SET(bestsp[db], ARCH_CONVERT, NULLDATAOFF);
1559 } 1559 }
1560 /* 1560 /*
1561 * If the data block was not the first one, drop it. 1561 * If the data block was not the first one, drop it.
1562 */ 1562 */
1563 else if (db != mp->m_dirdatablk && dbp != NULL) { 1563 else if (db != mp->m_dirdatablk && dbp != NULL) {
1564 xfs_da_buf_done(dbp); 1564 xfs_da_buf_done(dbp);
1565 dbp = NULL; 1565 dbp = NULL;
1566 } 1566 }
1567 xfs_dir2_leaf_check(dp, lbp); 1567 xfs_dir2_leaf_check(dp, lbp);
1568 /* 1568 /*
1569 * See if we can convert to block form. 1569 * See if we can convert to block form.
1570 */ 1570 */
1571 return xfs_dir2_leaf_to_block(args, lbp, dbp); 1571 return xfs_dir2_leaf_to_block(args, lbp, dbp);
1572 } 1572 }
1573 1573
1574 /* 1574 /*
1575 * Replace the inode number in a leaf format directory entry. 1575 * Replace the inode number in a leaf format directory entry.
1576 */ 1576 */
1577 int /* error */ 1577 int /* error */
1578 xfs_dir2_leaf_replace( 1578 xfs_dir2_leaf_replace(
1579 xfs_da_args_t *args) /* operation arguments */ 1579 xfs_da_args_t *args) /* operation arguments */
1580 { 1580 {
1581 xfs_dabuf_t *dbp; /* data block buffer */ 1581 xfs_dabuf_t *dbp; /* data block buffer */
1582 xfs_dir2_data_entry_t *dep; /* data block entry */ 1582 xfs_dir2_data_entry_t *dep; /* data block entry */
1583 xfs_inode_t *dp; /* incore directory inode */ 1583 xfs_inode_t *dp; /* incore directory inode */
1584 int error; /* error return code */ 1584 int error; /* error return code */
1585 int index; /* index of leaf entry */ 1585 int index; /* index of leaf entry */
1586 xfs_dabuf_t *lbp; /* leaf buffer */ 1586 xfs_dabuf_t *lbp; /* leaf buffer */
1587 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1587 xfs_dir2_leaf_t *leaf; /* leaf structure */
1588 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 1588 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
1589 xfs_trans_t *tp; /* transaction pointer */ 1589 xfs_trans_t *tp; /* transaction pointer */
1590 1590
1591 xfs_dir2_trace_args("leaf_replace", args); 1591 xfs_dir2_trace_args("leaf_replace", args);
1592 /* 1592 /*
1593 * Look up the entry. 1593 * Look up the entry.
1594 */ 1594 */
1595 if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { 1595 if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) {
1596 return error; 1596 return error;
1597 } 1597 }
1598 dp = args->dp; 1598 dp = args->dp;
1599 leaf = lbp->data; 1599 leaf = lbp->data;
1600 /* 1600 /*
1601 * Point to the leaf entry, get data address from it. 1601 * Point to the leaf entry, get data address from it.
1602 */ 1602 */
1603 lep = &leaf->ents[index]; 1603 lep = &leaf->ents[index];
1604 /* 1604 /*
1605 * Point to the data entry. 1605 * Point to the data entry.
1606 */ 1606 */
1607 dep = (xfs_dir2_data_entry_t *) 1607 dep = (xfs_dir2_data_entry_t *)
1608 ((char *)dbp->data + 1608 ((char *)dbp->data +
1609 XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, INT_GET(lep->address, ARCH_CONVERT))); 1609 XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, INT_GET(lep->address, ARCH_CONVERT)));
1610 ASSERT(args->inumber != INT_GET(dep->inumber, ARCH_CONVERT)); 1610 ASSERT(args->inumber != INT_GET(dep->inumber, ARCH_CONVERT));
1611 /* 1611 /*
1612 * Put the new inode number in, log it. 1612 * Put the new inode number in, log it.
1613 */ 1613 */
1614 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 1614 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
1615 tp = args->trans; 1615 tp = args->trans;
1616 xfs_dir2_data_log_entry(tp, dbp, dep); 1616 xfs_dir2_data_log_entry(tp, dbp, dep);
1617 xfs_da_buf_done(dbp); 1617 xfs_da_buf_done(dbp);
1618 xfs_dir2_leaf_check(dp, lbp); 1618 xfs_dir2_leaf_check(dp, lbp);
1619 xfs_da_brelse(tp, lbp); 1619 xfs_da_brelse(tp, lbp);
1620 return 0; 1620 return 0;
1621 } 1621 }
1622 1622
1623 /* 1623 /*
1624 * Return index in the leaf block (lbp) which is either the first 1624 * Return index in the leaf block (lbp) which is either the first
1625 * one with this hash value, or if there are none, the insert point 1625 * one with this hash value, or if there are none, the insert point
1626 * for that hash value. 1626 * for that hash value.
1627 */ 1627 */
1628 int /* index value */ 1628 int /* index value */
1629 xfs_dir2_leaf_search_hash( 1629 xfs_dir2_leaf_search_hash(
1630 xfs_da_args_t *args, /* operation arguments */ 1630 xfs_da_args_t *args, /* operation arguments */
1631 xfs_dabuf_t *lbp) /* leaf buffer */ 1631 xfs_dabuf_t *lbp) /* leaf buffer */
1632 { 1632 {
1633 xfs_dahash_t hash=0; /* hash from this entry */ 1633 xfs_dahash_t hash=0; /* hash from this entry */
1634 xfs_dahash_t hashwant; /* hash value looking for */ 1634 xfs_dahash_t hashwant; /* hash value looking for */
1635 int high; /* high leaf index */ 1635 int high; /* high leaf index */
1636 int low; /* low leaf index */ 1636 int low; /* low leaf index */
1637 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1637 xfs_dir2_leaf_t *leaf; /* leaf structure */
1638 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 1638 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
1639 int mid=0; /* current leaf index */ 1639 int mid=0; /* current leaf index */
1640 1640
1641 leaf = lbp->data; 1641 leaf = lbp->data;
1642 #ifndef __KERNEL__ 1642 #ifndef __KERNEL__
1643 if (!leaf->hdr.count) 1643 if (!leaf->hdr.count)
1644 return 0; 1644 return 0;
1645 #endif 1645 #endif
1646 /* 1646 /*
1647 * Note, the table cannot be empty, so we have to go through the loop. 1647 * Note, the table cannot be empty, so we have to go through the loop.
1648 * Binary search the leaf entries looking for our hash value. 1648 * Binary search the leaf entries looking for our hash value.
1649 */ 1649 */
1650 for (lep = leaf->ents, low = 0, high = INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1, 1650 for (lep = leaf->ents, low = 0, high = INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1,
1651 hashwant = args->hashval; 1651 hashwant = args->hashval;
1652 low <= high; ) { 1652 low <= high; ) {
1653 mid = (low + high) >> 1; 1653 mid = (low + high) >> 1;
1654 if ((hash = INT_GET(lep[mid].hashval, ARCH_CONVERT)) == hashwant) 1654 if ((hash = INT_GET(lep[mid].hashval, ARCH_CONVERT)) == hashwant)
1655 break; 1655 break;
1656 if (hash < hashwant) 1656 if (hash < hashwant)
1657 low = mid + 1; 1657 low = mid + 1;
1658 else 1658 else
1659 high = mid - 1; 1659 high = mid - 1;
1660 } 1660 }
1661 /* 1661 /*
1662 * Found one, back up through all the equal hash values. 1662 * Found one, back up through all the equal hash values.
1663 */ 1663 */
1664 if (hash == hashwant) { 1664 if (hash == hashwant) {
1665 while (mid > 0 && INT_GET(lep[mid - 1].hashval, ARCH_CONVERT) == hashwant) { 1665 while (mid > 0 && INT_GET(lep[mid - 1].hashval, ARCH_CONVERT) == hashwant) {
1666 mid--; 1666 mid--;
1667 } 1667 }
1668 } 1668 }
1669 /* 1669 /*
1670 * Need to point to an entry higher than ours. 1670 * Need to point to an entry higher than ours.
1671 */ 1671 */
1672 else if (hash < hashwant) 1672 else if (hash < hashwant)
1673 mid++; 1673 mid++;
1674 return mid; 1674 return mid;
1675 } 1675 }
1676 1676
1677 /* 1677 /*
1678 * Trim off a trailing data block. We know it's empty since the leaf 1678 * Trim off a trailing data block. We know it's empty since the leaf
1679 * freespace table says so. 1679 * freespace table says so.
1680 */ 1680 */
1681 int /* error */ 1681 int /* error */
1682 xfs_dir2_leaf_trim_data( 1682 xfs_dir2_leaf_trim_data(
1683 xfs_da_args_t *args, /* operation arguments */ 1683 xfs_da_args_t *args, /* operation arguments */
1684 xfs_dabuf_t *lbp, /* leaf buffer */ 1684 xfs_dabuf_t *lbp, /* leaf buffer */
1685 xfs_dir2_db_t db) /* data block number */ 1685 xfs_dir2_db_t db) /* data block number */
1686 { 1686 {
1687 xfs_dir2_data_off_t *bestsp; /* leaf bests table */ 1687 xfs_dir2_data_off_t *bestsp; /* leaf bests table */
1688 #ifdef DEBUG 1688 #ifdef DEBUG
1689 xfs_dir2_data_t *data; /* data block structure */ 1689 xfs_dir2_data_t *data; /* data block structure */
1690 #endif 1690 #endif
1691 xfs_dabuf_t *dbp; /* data block buffer */ 1691 xfs_dabuf_t *dbp; /* data block buffer */
1692 xfs_inode_t *dp; /* incore directory inode */ 1692 xfs_inode_t *dp; /* incore directory inode */
1693 int error; /* error return value */ 1693 int error; /* error return value */
1694 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1694 xfs_dir2_leaf_t *leaf; /* leaf structure */
1695 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 1695 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
1696 xfs_mount_t *mp; /* filesystem mount point */ 1696 xfs_mount_t *mp; /* filesystem mount point */
1697 xfs_trans_t *tp; /* transaction pointer */ 1697 xfs_trans_t *tp; /* transaction pointer */
1698 1698
1699 dp = args->dp; 1699 dp = args->dp;
1700 mp = dp->i_mount; 1700 mp = dp->i_mount;
1701 tp = args->trans; 1701 tp = args->trans;
1702 /* 1702 /*
1703 * Read the offending data block. We need its buffer. 1703 * Read the offending data block. We need its buffer.
1704 */ 1704 */
1705 if ((error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, db), -1, &dbp, 1705 if ((error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, db), -1, &dbp,
1706 XFS_DATA_FORK))) { 1706 XFS_DATA_FORK))) {
1707 return error; 1707 return error;
1708 } 1708 }
1709 #ifdef DEBUG 1709 #ifdef DEBUG
1710 data = dbp->data; 1710 data = dbp->data;
1711 ASSERT(INT_GET(data->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC); 1711 ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC);
1712 #endif 1712 #endif
1713 /* this seems to be an error 1713 /* this seems to be an error
1714 * data is only valid if DEBUG is defined? 1714 * data is only valid if DEBUG is defined?
1715 * RMC 09/08/1999 1715 * RMC 09/08/1999
1716 */ 1716 */
1717 1717
1718 leaf = lbp->data; 1718 leaf = lbp->data;
1719 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); 1719 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
1720 ASSERT(INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT) == 1720 ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) ==
1721 mp->m_dirblksize - (uint)sizeof(data->hdr)); 1721 mp->m_dirblksize - (uint)sizeof(data->hdr));
1722 ASSERT(db == INT_GET(ltp->bestcount, ARCH_CONVERT) - 1); 1722 ASSERT(db == INT_GET(ltp->bestcount, ARCH_CONVERT) - 1);
1723 /* 1723 /*
1724 * Get rid of the data block. 1724 * Get rid of the data block.
1725 */ 1725 */
1726 if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { 1726 if ((error = xfs_dir2_shrink_inode(args, db, dbp))) {
1727 ASSERT(error != ENOSPC); 1727 ASSERT(error != ENOSPC);
1728 xfs_da_brelse(tp, dbp); 1728 xfs_da_brelse(tp, dbp);
1729 return error; 1729 return error;
1730 } 1730 }
1731 /* 1731 /*
1732 * Eliminate the last bests entry from the table. 1732 * Eliminate the last bests entry from the table.
1733 */ 1733 */
1734 bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); 1734 bestsp = XFS_DIR2_LEAF_BESTS_P(ltp);
1735 INT_MOD(ltp->bestcount, ARCH_CONVERT, -1); 1735 INT_MOD(ltp->bestcount, ARCH_CONVERT, -1);
1736 memmove(&bestsp[1], &bestsp[0], INT_GET(ltp->bestcount, ARCH_CONVERT) * sizeof(*bestsp)); 1736 memmove(&bestsp[1], &bestsp[0], INT_GET(ltp->bestcount, ARCH_CONVERT) * sizeof(*bestsp));
1737 xfs_dir2_leaf_log_tail(tp, lbp); 1737 xfs_dir2_leaf_log_tail(tp, lbp);
1738 xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1); 1738 xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1);
1739 return 0; 1739 return 0;
1740 } 1740 }
1741 1741
1742 /* 1742 /*
1743 * Convert node form directory to leaf form directory. 1743 * Convert node form directory to leaf form directory.
1744 * The root of the node form dir needs to already be a LEAFN block. 1744 * The root of the node form dir needs to already be a LEAFN block.
1745 * Just return if we can't do anything. 1745 * Just return if we can't do anything.
1746 */ 1746 */
1747 int /* error */ 1747 int /* error */
1748 xfs_dir2_node_to_leaf( 1748 xfs_dir2_node_to_leaf(
1749 xfs_da_state_t *state) /* directory operation state */ 1749 xfs_da_state_t *state) /* directory operation state */
1750 { 1750 {
1751 xfs_da_args_t *args; /* operation arguments */ 1751 xfs_da_args_t *args; /* operation arguments */
1752 xfs_inode_t *dp; /* incore directory inode */ 1752 xfs_inode_t *dp; /* incore directory inode */
1753 int error; /* error return code */ 1753 int error; /* error return code */
1754 xfs_dabuf_t *fbp; /* buffer for freespace block */ 1754 xfs_dabuf_t *fbp; /* buffer for freespace block */
1755 xfs_fileoff_t fo; /* freespace file offset */ 1755 xfs_fileoff_t fo; /* freespace file offset */
1756 xfs_dir2_free_t *free; /* freespace structure */ 1756 xfs_dir2_free_t *free; /* freespace structure */
1757 xfs_dabuf_t *lbp; /* buffer for leaf block */ 1757 xfs_dabuf_t *lbp; /* buffer for leaf block */
1758 xfs_dir2_leaf_tail_t *ltp; /* tail of leaf structure */ 1758 xfs_dir2_leaf_tail_t *ltp; /* tail of leaf structure */
1759 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1759 xfs_dir2_leaf_t *leaf; /* leaf structure */
1760 xfs_mount_t *mp; /* filesystem mount point */ 1760 xfs_mount_t *mp; /* filesystem mount point */
1761 int rval; /* successful free trim? */ 1761 int rval; /* successful free trim? */
1762 xfs_trans_t *tp; /* transaction pointer */ 1762 xfs_trans_t *tp; /* transaction pointer */
1763 1763
1764 /* 1764 /*
1765 * There's more than a leaf level in the btree, so there must 1765 * There's more than a leaf level in the btree, so there must
1766 * be multiple leafn blocks. Give up. 1766 * be multiple leafn blocks. Give up.
1767 */ 1767 */
1768 if (state->path.active > 1) 1768 if (state->path.active > 1)
1769 return 0; 1769 return 0;
1770 args = state->args; 1770 args = state->args;
1771 xfs_dir2_trace_args("node_to_leaf", args); 1771 xfs_dir2_trace_args("node_to_leaf", args);
1772 mp = state->mp; 1772 mp = state->mp;
1773 dp = args->dp; 1773 dp = args->dp;
1774 tp = args->trans; 1774 tp = args->trans;
1775 /* 1775 /*
1776 * Get the last offset in the file. 1776 * Get the last offset in the file.
1777 */ 1777 */
1778 if ((error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK))) { 1778 if ((error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK))) {
1779 return error; 1779 return error;
1780 } 1780 }
1781 fo -= mp->m_dirblkfsbs; 1781 fo -= mp->m_dirblkfsbs;
1782 /* 1782 /*
1783 * If there are freespace blocks other than the first one, 1783 * If there are freespace blocks other than the first one,
1784 * take this opportunity to remove trailing empty freespace blocks 1784 * take this opportunity to remove trailing empty freespace blocks
1785 * that may have been left behind during no-space-reservation 1785 * that may have been left behind during no-space-reservation
1786 * operations. 1786 * operations.
1787 */ 1787 */
1788 while (fo > mp->m_dirfreeblk) { 1788 while (fo > mp->m_dirfreeblk) {
1789 if ((error = xfs_dir2_node_trim_free(args, fo, &rval))) { 1789 if ((error = xfs_dir2_node_trim_free(args, fo, &rval))) {
1790 return error; 1790 return error;
1791 } 1791 }
1792 if (rval) 1792 if (rval)
1793 fo -= mp->m_dirblkfsbs; 1793 fo -= mp->m_dirblkfsbs;
1794 else 1794 else
1795 return 0; 1795 return 0;
1796 } 1796 }
1797 /* 1797 /*
1798 * Now find the block just before the freespace block. 1798 * Now find the block just before the freespace block.
1799 */ 1799 */
1800 if ((error = xfs_bmap_last_before(tp, dp, &fo, XFS_DATA_FORK))) { 1800 if ((error = xfs_bmap_last_before(tp, dp, &fo, XFS_DATA_FORK))) {
1801 return error; 1801 return error;
1802 } 1802 }
1803 /* 1803 /*
1804 * If it's not the single leaf block, give up. 1804 * If it's not the single leaf block, give up.
1805 */ 1805 */
1806 if (XFS_FSB_TO_B(mp, fo) > XFS_DIR2_LEAF_OFFSET + mp->m_dirblksize) 1806 if (XFS_FSB_TO_B(mp, fo) > XFS_DIR2_LEAF_OFFSET + mp->m_dirblksize)
1807 return 0; 1807 return 0;
1808 lbp = state->path.blk[0].bp; 1808 lbp = state->path.blk[0].bp;
1809 leaf = lbp->data; 1809 leaf = lbp->data;
1810 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); 1810 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
1811 /* 1811 /*
1812 * Read the freespace block. 1812 * Read the freespace block.
1813 */ 1813 */
1814 if ((error = xfs_da_read_buf(tp, dp, mp->m_dirfreeblk, -1, &fbp, 1814 if ((error = xfs_da_read_buf(tp, dp, mp->m_dirfreeblk, -1, &fbp,
1815 XFS_DATA_FORK))) { 1815 XFS_DATA_FORK))) {
1816 return error; 1816 return error;
1817 } 1817 }
1818 free = fbp->data; 1818 free = fbp->data;
1819 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); 1819 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
1820 ASSERT(!free->hdr.firstdb); 1820 ASSERT(!free->hdr.firstdb);
1821 /* 1821 /*
1822 * Now see if the leafn and free data will fit in a leaf1. 1822 * Now see if the leafn and free data will fit in a leaf1.
1823 * If not, release the buffer and give up. 1823 * If not, release the buffer and give up.
1824 */ 1824 */
1825 if ((uint)sizeof(leaf->hdr) + 1825 if ((uint)sizeof(leaf->hdr) +
1826 (INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT)) * (uint)sizeof(leaf->ents[0]) + 1826 (INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT)) * (uint)sizeof(leaf->ents[0]) +
1827 INT_GET(free->hdr.nvalid, ARCH_CONVERT) * (uint)sizeof(leaf->bests[0]) + 1827 INT_GET(free->hdr.nvalid, ARCH_CONVERT) * (uint)sizeof(leaf->bests[0]) +
1828 (uint)sizeof(leaf->tail) > 1828 (uint)sizeof(leaf->tail) >
1829 mp->m_dirblksize) { 1829 mp->m_dirblksize) {
1830 xfs_da_brelse(tp, fbp); 1830 xfs_da_brelse(tp, fbp);
1831 return 0; 1831 return 0;
1832 } 1832 }
1833 /* 1833 /*
1834 * If the leaf has any stale entries in it, compress them out. 1834 * If the leaf has any stale entries in it, compress them out.
1835 * The compact routine will log the header. 1835 * The compact routine will log the header.
1836 */ 1836 */
1837 if (INT_GET(leaf->hdr.stale, ARCH_CONVERT)) 1837 if (INT_GET(leaf->hdr.stale, ARCH_CONVERT))
1838 xfs_dir2_leaf_compact(args, lbp); 1838 xfs_dir2_leaf_compact(args, lbp);
1839 else 1839 else
1840 xfs_dir2_leaf_log_header(tp, lbp); 1840 xfs_dir2_leaf_log_header(tp, lbp);
1841 INT_SET(leaf->hdr.info.magic, ARCH_CONVERT, XFS_DIR2_LEAF1_MAGIC); 1841 INT_SET(leaf->hdr.info.magic, ARCH_CONVERT, XFS_DIR2_LEAF1_MAGIC);
1842 /* 1842 /*
1843 * Set up the leaf tail from the freespace block. 1843 * Set up the leaf tail from the freespace block.
1844 */ 1844 */
1845 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); 1845 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
1846 INT_COPY(ltp->bestcount, free->hdr.nvalid, ARCH_CONVERT); 1846 INT_COPY(ltp->bestcount, free->hdr.nvalid, ARCH_CONVERT);
1847 /* 1847 /*
1848 * Set up the leaf bests table. 1848 * Set up the leaf bests table.
1849 */ 1849 */
1850 memcpy(XFS_DIR2_LEAF_BESTS_P(ltp), free->bests, 1850 memcpy(XFS_DIR2_LEAF_BESTS_P(ltp), free->bests,
1851 INT_GET(ltp->bestcount, ARCH_CONVERT) * sizeof(leaf->bests[0])); 1851 INT_GET(ltp->bestcount, ARCH_CONVERT) * sizeof(leaf->bests[0]));
1852 xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1); 1852 xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1);
1853 xfs_dir2_leaf_log_tail(tp, lbp); 1853 xfs_dir2_leaf_log_tail(tp, lbp);
1854 xfs_dir2_leaf_check(dp, lbp); 1854 xfs_dir2_leaf_check(dp, lbp);
1855 /* 1855 /*
1856 * Get rid of the freespace block. 1856 * Get rid of the freespace block.
1857 */ 1857 */
1858 error = xfs_dir2_shrink_inode(args, XFS_DIR2_FREE_FIRSTDB(mp), fbp); 1858 error = xfs_dir2_shrink_inode(args, XFS_DIR2_FREE_FIRSTDB(mp), fbp);
1859 if (error) { 1859 if (error) {
1860 /* 1860 /*
1861 * This can't fail here because it can only happen when 1861 * This can't fail here because it can only happen when
1862 * punching out the middle of an extent, and this is an 1862 * punching out the middle of an extent, and this is an
1863 * isolated block. 1863 * isolated block.
1864 */ 1864 */
1865 ASSERT(error != ENOSPC); 1865 ASSERT(error != ENOSPC);
1866 return error; 1866 return error;
1867 } 1867 }
1868 fbp = NULL; 1868 fbp = NULL;
1869 /* 1869 /*
1870 * Now see if we can convert the single-leaf directory 1870 * Now see if we can convert the single-leaf directory
1871 * down to a block form directory. 1871 * down to a block form directory.
1872 * This routine always kills the dabuf for the leaf, so 1872 * This routine always kills the dabuf for the leaf, so
1873 * eliminate it from the path. 1873 * eliminate it from the path.
1874 */ 1874 */
1875 error = xfs_dir2_leaf_to_block(args, lbp, NULL); 1875 error = xfs_dir2_leaf_to_block(args, lbp, NULL);
1876 state->path.blk[0].bp = NULL; 1876 state->path.blk[0].bp = NULL;
1877 return error; 1877 return error;
1878 } 1878 }
1879 1879
fs/xfs/xfs_dir2_node.c
1 /* 1 /*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 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 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 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, 15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18 #include "xfs.h" 18 #include "xfs.h"
19 #include "xfs_fs.h" 19 #include "xfs_fs.h"
20 #include "xfs_types.h" 20 #include "xfs_types.h"
21 #include "xfs_log.h" 21 #include "xfs_log.h"
22 #include "xfs_inum.h" 22 #include "xfs_inum.h"
23 #include "xfs_trans.h" 23 #include "xfs_trans.h"
24 #include "xfs_sb.h" 24 #include "xfs_sb.h"
25 #include "xfs_dir.h" 25 #include "xfs_dir.h"
26 #include "xfs_dir2.h" 26 #include "xfs_dir2.h"
27 #include "xfs_dmapi.h" 27 #include "xfs_dmapi.h"
28 #include "xfs_mount.h" 28 #include "xfs_mount.h"
29 #include "xfs_da_btree.h" 29 #include "xfs_da_btree.h"
30 #include "xfs_bmap_btree.h" 30 #include "xfs_bmap_btree.h"
31 #include "xfs_dir_sf.h" 31 #include "xfs_dir_sf.h"
32 #include "xfs_dir2_sf.h" 32 #include "xfs_dir2_sf.h"
33 #include "xfs_attr_sf.h" 33 #include "xfs_attr_sf.h"
34 #include "xfs_dinode.h" 34 #include "xfs_dinode.h"
35 #include "xfs_inode.h" 35 #include "xfs_inode.h"
36 #include "xfs_bmap.h" 36 #include "xfs_bmap.h"
37 #include "xfs_dir2_data.h" 37 #include "xfs_dir2_data.h"
38 #include "xfs_dir2_leaf.h" 38 #include "xfs_dir2_leaf.h"
39 #include "xfs_dir2_block.h" 39 #include "xfs_dir2_block.h"
40 #include "xfs_dir2_node.h" 40 #include "xfs_dir2_node.h"
41 #include "xfs_dir2_trace.h" 41 #include "xfs_dir2_trace.h"
42 #include "xfs_error.h" 42 #include "xfs_error.h"
43 43
44 /* 44 /*
45 * Function declarations. 45 * Function declarations.
46 */ 46 */
47 static void xfs_dir2_free_log_header(xfs_trans_t *tp, xfs_dabuf_t *bp); 47 static void xfs_dir2_free_log_header(xfs_trans_t *tp, xfs_dabuf_t *bp);
48 static int xfs_dir2_leafn_add(xfs_dabuf_t *bp, xfs_da_args_t *args, int index); 48 static int xfs_dir2_leafn_add(xfs_dabuf_t *bp, xfs_da_args_t *args, int index);
49 #ifdef DEBUG 49 #ifdef DEBUG
50 static void xfs_dir2_leafn_check(xfs_inode_t *dp, xfs_dabuf_t *bp); 50 static void xfs_dir2_leafn_check(xfs_inode_t *dp, xfs_dabuf_t *bp);
51 #else 51 #else
52 #define xfs_dir2_leafn_check(dp, bp) 52 #define xfs_dir2_leafn_check(dp, bp)
53 #endif 53 #endif
54 static void xfs_dir2_leafn_moveents(xfs_da_args_t *args, xfs_dabuf_t *bp_s, 54 static void xfs_dir2_leafn_moveents(xfs_da_args_t *args, xfs_dabuf_t *bp_s,
55 int start_s, xfs_dabuf_t *bp_d, int start_d, 55 int start_s, xfs_dabuf_t *bp_d, int start_d,
56 int count); 56 int count);
57 static void xfs_dir2_leafn_rebalance(xfs_da_state_t *state, 57 static void xfs_dir2_leafn_rebalance(xfs_da_state_t *state,
58 xfs_da_state_blk_t *blk1, 58 xfs_da_state_blk_t *blk1,
59 xfs_da_state_blk_t *blk2); 59 xfs_da_state_blk_t *blk2);
60 static int xfs_dir2_leafn_remove(xfs_da_args_t *args, xfs_dabuf_t *bp, 60 static int xfs_dir2_leafn_remove(xfs_da_args_t *args, xfs_dabuf_t *bp,
61 int index, xfs_da_state_blk_t *dblk, 61 int index, xfs_da_state_blk_t *dblk,
62 int *rval); 62 int *rval);
63 static int xfs_dir2_node_addname_int(xfs_da_args_t *args, 63 static int xfs_dir2_node_addname_int(xfs_da_args_t *args,
64 xfs_da_state_blk_t *fblk); 64 xfs_da_state_blk_t *fblk);
65 65
66 /* 66 /*
67 * Log entries from a freespace block. 67 * Log entries from a freespace block.
68 */ 68 */
69 void 69 void
70 xfs_dir2_free_log_bests( 70 xfs_dir2_free_log_bests(
71 xfs_trans_t *tp, /* transaction pointer */ 71 xfs_trans_t *tp, /* transaction pointer */
72 xfs_dabuf_t *bp, /* freespace buffer */ 72 xfs_dabuf_t *bp, /* freespace buffer */
73 int first, /* first entry to log */ 73 int first, /* first entry to log */
74 int last) /* last entry to log */ 74 int last) /* last entry to log */
75 { 75 {
76 xfs_dir2_free_t *free; /* freespace structure */ 76 xfs_dir2_free_t *free; /* freespace structure */
77 77
78 free = bp->data; 78 free = bp->data;
79 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); 79 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
80 xfs_da_log_buf(tp, bp, 80 xfs_da_log_buf(tp, bp,
81 (uint)((char *)&free->bests[first] - (char *)free), 81 (uint)((char *)&free->bests[first] - (char *)free),
82 (uint)((char *)&free->bests[last] - (char *)free + 82 (uint)((char *)&free->bests[last] - (char *)free +
83 sizeof(free->bests[0]) - 1)); 83 sizeof(free->bests[0]) - 1));
84 } 84 }
85 85
86 /* 86 /*
87 * Log header from a freespace block. 87 * Log header from a freespace block.
88 */ 88 */
89 static void 89 static void
90 xfs_dir2_free_log_header( 90 xfs_dir2_free_log_header(
91 xfs_trans_t *tp, /* transaction pointer */ 91 xfs_trans_t *tp, /* transaction pointer */
92 xfs_dabuf_t *bp) /* freespace buffer */ 92 xfs_dabuf_t *bp) /* freespace buffer */
93 { 93 {
94 xfs_dir2_free_t *free; /* freespace structure */ 94 xfs_dir2_free_t *free; /* freespace structure */
95 95
96 free = bp->data; 96 free = bp->data;
97 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); 97 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
98 xfs_da_log_buf(tp, bp, (uint)((char *)&free->hdr - (char *)free), 98 xfs_da_log_buf(tp, bp, (uint)((char *)&free->hdr - (char *)free),
99 (uint)(sizeof(xfs_dir2_free_hdr_t) - 1)); 99 (uint)(sizeof(xfs_dir2_free_hdr_t) - 1));
100 } 100 }
101 101
102 /* 102 /*
103 * Convert a leaf-format directory to a node-format directory. 103 * Convert a leaf-format directory to a node-format directory.
104 * We need to change the magic number of the leaf block, and copy 104 * We need to change the magic number of the leaf block, and copy
105 * the freespace table out of the leaf block into its own block. 105 * the freespace table out of the leaf block into its own block.
106 */ 106 */
107 int /* error */ 107 int /* error */
108 xfs_dir2_leaf_to_node( 108 xfs_dir2_leaf_to_node(
109 xfs_da_args_t *args, /* operation arguments */ 109 xfs_da_args_t *args, /* operation arguments */
110 xfs_dabuf_t *lbp) /* leaf buffer */ 110 xfs_dabuf_t *lbp) /* leaf buffer */
111 { 111 {
112 xfs_inode_t *dp; /* incore directory inode */ 112 xfs_inode_t *dp; /* incore directory inode */
113 int error; /* error return value */ 113 int error; /* error return value */
114 xfs_dabuf_t *fbp; /* freespace buffer */ 114 xfs_dabuf_t *fbp; /* freespace buffer */
115 xfs_dir2_db_t fdb; /* freespace block number */ 115 xfs_dir2_db_t fdb; /* freespace block number */
116 xfs_dir2_free_t *free; /* freespace structure */ 116 xfs_dir2_free_t *free; /* freespace structure */
117 xfs_dir2_data_off_t *from; /* pointer to freespace entry */ 117 xfs_dir2_data_off_t *from; /* pointer to freespace entry */
118 int i; /* leaf freespace index */ 118 int i; /* leaf freespace index */
119 xfs_dir2_leaf_t *leaf; /* leaf structure */ 119 xfs_dir2_leaf_t *leaf; /* leaf structure */
120 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 120 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
121 xfs_mount_t *mp; /* filesystem mount point */ 121 xfs_mount_t *mp; /* filesystem mount point */
122 int n; /* count of live freespc ents */ 122 int n; /* count of live freespc ents */
123 xfs_dir2_data_off_t off; /* freespace entry value */ 123 xfs_dir2_data_off_t off; /* freespace entry value */
124 xfs_dir2_data_off_t *to; /* pointer to freespace entry */ 124 xfs_dir2_data_off_t *to; /* pointer to freespace entry */
125 xfs_trans_t *tp; /* transaction pointer */ 125 xfs_trans_t *tp; /* transaction pointer */
126 126
127 xfs_dir2_trace_args_b("leaf_to_node", args, lbp); 127 xfs_dir2_trace_args_b("leaf_to_node", args, lbp);
128 dp = args->dp; 128 dp = args->dp;
129 mp = dp->i_mount; 129 mp = dp->i_mount;
130 tp = args->trans; 130 tp = args->trans;
131 /* 131 /*
132 * Add a freespace block to the directory. 132 * Add a freespace block to the directory.
133 */ 133 */
134 if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, &fdb))) { 134 if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, &fdb))) {
135 return error; 135 return error;
136 } 136 }
137 ASSERT(fdb == XFS_DIR2_FREE_FIRSTDB(mp)); 137 ASSERT(fdb == XFS_DIR2_FREE_FIRSTDB(mp));
138 /* 138 /*
139 * Get the buffer for the new freespace block. 139 * Get the buffer for the new freespace block.
140 */ 140 */
141 if ((error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, fdb), -1, &fbp, 141 if ((error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, fdb), -1, &fbp,
142 XFS_DATA_FORK))) { 142 XFS_DATA_FORK))) {
143 return error; 143 return error;
144 } 144 }
145 ASSERT(fbp != NULL); 145 ASSERT(fbp != NULL);
146 free = fbp->data; 146 free = fbp->data;
147 leaf = lbp->data; 147 leaf = lbp->data;
148 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); 148 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
149 /* 149 /*
150 * Initialize the freespace block header. 150 * Initialize the freespace block header.
151 */ 151 */
152 INT_SET(free->hdr.magic, ARCH_CONVERT, XFS_DIR2_FREE_MAGIC); 152 INT_SET(free->hdr.magic, ARCH_CONVERT, XFS_DIR2_FREE_MAGIC);
153 free->hdr.firstdb = 0; 153 free->hdr.firstdb = 0;
154 ASSERT(INT_GET(ltp->bestcount, ARCH_CONVERT) <= (uint)dp->i_d.di_size / mp->m_dirblksize); 154 ASSERT(INT_GET(ltp->bestcount, ARCH_CONVERT) <= (uint)dp->i_d.di_size / mp->m_dirblksize);
155 INT_COPY(free->hdr.nvalid, ltp->bestcount, ARCH_CONVERT); 155 INT_COPY(free->hdr.nvalid, ltp->bestcount, ARCH_CONVERT);
156 /* 156 /*
157 * Copy freespace entries from the leaf block to the new block. 157 * Copy freespace entries from the leaf block to the new block.
158 * Count active entries. 158 * Count active entries.
159 */ 159 */
160 for (i = n = 0, from = XFS_DIR2_LEAF_BESTS_P(ltp), to = free->bests; 160 for (i = n = 0, from = XFS_DIR2_LEAF_BESTS_P(ltp), to = free->bests;
161 i < INT_GET(ltp->bestcount, ARCH_CONVERT); i++, from++, to++) { 161 i < INT_GET(ltp->bestcount, ARCH_CONVERT); i++, from++, to++) {
162 if ((off = INT_GET(*from, ARCH_CONVERT)) != NULLDATAOFF) 162 if ((off = INT_GET(*from, ARCH_CONVERT)) != NULLDATAOFF)
163 n++; 163 n++;
164 INT_SET(*to, ARCH_CONVERT, off); 164 INT_SET(*to, ARCH_CONVERT, off);
165 } 165 }
166 INT_SET(free->hdr.nused, ARCH_CONVERT, n); 166 INT_SET(free->hdr.nused, ARCH_CONVERT, n);
167 INT_SET(leaf->hdr.info.magic, ARCH_CONVERT, XFS_DIR2_LEAFN_MAGIC); 167 INT_SET(leaf->hdr.info.magic, ARCH_CONVERT, XFS_DIR2_LEAFN_MAGIC);
168 /* 168 /*
169 * Log everything. 169 * Log everything.
170 */ 170 */
171 xfs_dir2_leaf_log_header(tp, lbp); 171 xfs_dir2_leaf_log_header(tp, lbp);
172 xfs_dir2_free_log_header(tp, fbp); 172 xfs_dir2_free_log_header(tp, fbp);
173 xfs_dir2_free_log_bests(tp, fbp, 0, INT_GET(free->hdr.nvalid, ARCH_CONVERT) - 1); 173 xfs_dir2_free_log_bests(tp, fbp, 0, INT_GET(free->hdr.nvalid, ARCH_CONVERT) - 1);
174 xfs_da_buf_done(fbp); 174 xfs_da_buf_done(fbp);
175 xfs_dir2_leafn_check(dp, lbp); 175 xfs_dir2_leafn_check(dp, lbp);
176 return 0; 176 return 0;
177 } 177 }
178 178
179 /* 179 /*
180 * Add a leaf entry to a leaf block in a node-form directory. 180 * Add a leaf entry to a leaf block in a node-form directory.
181 * The other work necessary is done from the caller. 181 * The other work necessary is done from the caller.
182 */ 182 */
183 static int /* error */ 183 static int /* error */
184 xfs_dir2_leafn_add( 184 xfs_dir2_leafn_add(
185 xfs_dabuf_t *bp, /* leaf buffer */ 185 xfs_dabuf_t *bp, /* leaf buffer */
186 xfs_da_args_t *args, /* operation arguments */ 186 xfs_da_args_t *args, /* operation arguments */
187 int index) /* insertion pt for new entry */ 187 int index) /* insertion pt for new entry */
188 { 188 {
189 int compact; /* compacting stale leaves */ 189 int compact; /* compacting stale leaves */
190 xfs_inode_t *dp; /* incore directory inode */ 190 xfs_inode_t *dp; /* incore directory inode */
191 int highstale; /* next stale entry */ 191 int highstale; /* next stale entry */
192 xfs_dir2_leaf_t *leaf; /* leaf structure */ 192 xfs_dir2_leaf_t *leaf; /* leaf structure */
193 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 193 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
194 int lfloghigh; /* high leaf entry logging */ 194 int lfloghigh; /* high leaf entry logging */
195 int lfloglow; /* low leaf entry logging */ 195 int lfloglow; /* low leaf entry logging */
196 int lowstale; /* previous stale entry */ 196 int lowstale; /* previous stale entry */
197 xfs_mount_t *mp; /* filesystem mount point */ 197 xfs_mount_t *mp; /* filesystem mount point */
198 xfs_trans_t *tp; /* transaction pointer */ 198 xfs_trans_t *tp; /* transaction pointer */
199 199
200 xfs_dir2_trace_args_sb("leafn_add", args, index, bp); 200 xfs_dir2_trace_args_sb("leafn_add", args, index, bp);
201 dp = args->dp; 201 dp = args->dp;
202 mp = dp->i_mount; 202 mp = dp->i_mount;
203 tp = args->trans; 203 tp = args->trans;
204 leaf = bp->data; 204 leaf = bp->data;
205 205
206 /* 206 /*
207 * Quick check just to make sure we are not going to index 207 * Quick check just to make sure we are not going to index
208 * into other peoples memory 208 * into other peoples memory
209 */ 209 */
210 if (index < 0) 210 if (index < 0)
211 return XFS_ERROR(EFSCORRUPTED); 211 return XFS_ERROR(EFSCORRUPTED);
212 212
213 /* 213 /*
214 * If there are already the maximum number of leaf entries in 214 * If there are already the maximum number of leaf entries in
215 * the block, if there are no stale entries it won't fit. 215 * the block, if there are no stale entries it won't fit.
216 * Caller will do a split. If there are stale entries we'll do 216 * Caller will do a split. If there are stale entries we'll do
217 * a compact. 217 * a compact.
218 */ 218 */
219 219
220 if (INT_GET(leaf->hdr.count, ARCH_CONVERT) == XFS_DIR2_MAX_LEAF_ENTS(mp)) { 220 if (INT_GET(leaf->hdr.count, ARCH_CONVERT) == XFS_DIR2_MAX_LEAF_ENTS(mp)) {
221 if (!leaf->hdr.stale) 221 if (!leaf->hdr.stale)
222 return XFS_ERROR(ENOSPC); 222 return XFS_ERROR(ENOSPC);
223 compact = INT_GET(leaf->hdr.stale, ARCH_CONVERT) > 1; 223 compact = INT_GET(leaf->hdr.stale, ARCH_CONVERT) > 1;
224 } else 224 } else
225 compact = 0; 225 compact = 0;
226 ASSERT(index == 0 || INT_GET(leaf->ents[index - 1].hashval, ARCH_CONVERT) <= args->hashval); 226 ASSERT(index == 0 || INT_GET(leaf->ents[index - 1].hashval, ARCH_CONVERT) <= args->hashval);
227 ASSERT(index == INT_GET(leaf->hdr.count, ARCH_CONVERT) || 227 ASSERT(index == INT_GET(leaf->hdr.count, ARCH_CONVERT) ||
228 INT_GET(leaf->ents[index].hashval, ARCH_CONVERT) >= args->hashval); 228 INT_GET(leaf->ents[index].hashval, ARCH_CONVERT) >= args->hashval);
229 229
230 if (args->justcheck) 230 if (args->justcheck)
231 return 0; 231 return 0;
232 232
233 /* 233 /*
234 * Compact out all but one stale leaf entry. Leaves behind 234 * Compact out all but one stale leaf entry. Leaves behind
235 * the entry closest to index. 235 * the entry closest to index.
236 */ 236 */
237 if (compact) { 237 if (compact) {
238 xfs_dir2_leaf_compact_x1(bp, &index, &lowstale, &highstale, 238 xfs_dir2_leaf_compact_x1(bp, &index, &lowstale, &highstale,
239 &lfloglow, &lfloghigh); 239 &lfloglow, &lfloghigh);
240 } 240 }
241 /* 241 /*
242 * Set impossible logging indices for this case. 242 * Set impossible logging indices for this case.
243 */ 243 */
244 else if (leaf->hdr.stale) { 244 else if (leaf->hdr.stale) {
245 lfloglow = INT_GET(leaf->hdr.count, ARCH_CONVERT); 245 lfloglow = INT_GET(leaf->hdr.count, ARCH_CONVERT);
246 lfloghigh = -1; 246 lfloghigh = -1;
247 } 247 }
248 /* 248 /*
249 * No stale entries, just insert a space for the new entry. 249 * No stale entries, just insert a space for the new entry.
250 */ 250 */
251 if (!leaf->hdr.stale) { 251 if (!leaf->hdr.stale) {
252 lep = &leaf->ents[index]; 252 lep = &leaf->ents[index];
253 if (index < INT_GET(leaf->hdr.count, ARCH_CONVERT)) 253 if (index < INT_GET(leaf->hdr.count, ARCH_CONVERT))
254 memmove(lep + 1, lep, 254 memmove(lep + 1, lep,
255 (INT_GET(leaf->hdr.count, ARCH_CONVERT) - index) * sizeof(*lep)); 255 (INT_GET(leaf->hdr.count, ARCH_CONVERT) - index) * sizeof(*lep));
256 lfloglow = index; 256 lfloglow = index;
257 lfloghigh = INT_GET(leaf->hdr.count, ARCH_CONVERT); 257 lfloghigh = INT_GET(leaf->hdr.count, ARCH_CONVERT);
258 INT_MOD(leaf->hdr.count, ARCH_CONVERT, +1); 258 INT_MOD(leaf->hdr.count, ARCH_CONVERT, +1);
259 } 259 }
260 /* 260 /*
261 * There are stale entries. We'll use one for the new entry. 261 * There are stale entries. We'll use one for the new entry.
262 */ 262 */
263 else { 263 else {
264 /* 264 /*
265 * If we didn't do a compact then we need to figure out 265 * If we didn't do a compact then we need to figure out
266 * which stale entry will be used. 266 * which stale entry will be used.
267 */ 267 */
268 if (compact == 0) { 268 if (compact == 0) {
269 /* 269 /*
270 * Find first stale entry before our insertion point. 270 * Find first stale entry before our insertion point.
271 */ 271 */
272 for (lowstale = index - 1; 272 for (lowstale = index - 1;
273 lowstale >= 0 && 273 lowstale >= 0 &&
274 INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) != 274 INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) !=
275 XFS_DIR2_NULL_DATAPTR; 275 XFS_DIR2_NULL_DATAPTR;
276 lowstale--) 276 lowstale--)
277 continue; 277 continue;
278 /* 278 /*
279 * Find next stale entry after insertion point. 279 * Find next stale entry after insertion point.
280 * Stop looking if the answer would be worse than 280 * Stop looking if the answer would be worse than
281 * lowstale already found. 281 * lowstale already found.
282 */ 282 */
283 for (highstale = index; 283 for (highstale = index;
284 highstale < INT_GET(leaf->hdr.count, ARCH_CONVERT) && 284 highstale < INT_GET(leaf->hdr.count, ARCH_CONVERT) &&
285 INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) != 285 INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) !=
286 XFS_DIR2_NULL_DATAPTR && 286 XFS_DIR2_NULL_DATAPTR &&
287 (lowstale < 0 || 287 (lowstale < 0 ||
288 index - lowstale - 1 >= highstale - index); 288 index - lowstale - 1 >= highstale - index);
289 highstale++) 289 highstale++)
290 continue; 290 continue;
291 } 291 }
292 /* 292 /*
293 * Using the low stale entry. 293 * Using the low stale entry.
294 * Shift entries up toward the stale slot. 294 * Shift entries up toward the stale slot.
295 */ 295 */
296 if (lowstale >= 0 && 296 if (lowstale >= 0 &&
297 (highstale == INT_GET(leaf->hdr.count, ARCH_CONVERT) || 297 (highstale == INT_GET(leaf->hdr.count, ARCH_CONVERT) ||
298 index - lowstale - 1 < highstale - index)) { 298 index - lowstale - 1 < highstale - index)) {
299 ASSERT(INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) == 299 ASSERT(INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) ==
300 XFS_DIR2_NULL_DATAPTR); 300 XFS_DIR2_NULL_DATAPTR);
301 ASSERT(index - lowstale - 1 >= 0); 301 ASSERT(index - lowstale - 1 >= 0);
302 if (index - lowstale - 1 > 0) 302 if (index - lowstale - 1 > 0)
303 memmove(&leaf->ents[lowstale], 303 memmove(&leaf->ents[lowstale],
304 &leaf->ents[lowstale + 1], 304 &leaf->ents[lowstale + 1],
305 (index - lowstale - 1) * sizeof(*lep)); 305 (index - lowstale - 1) * sizeof(*lep));
306 lep = &leaf->ents[index - 1]; 306 lep = &leaf->ents[index - 1];
307 lfloglow = MIN(lowstale, lfloglow); 307 lfloglow = MIN(lowstale, lfloglow);
308 lfloghigh = MAX(index - 1, lfloghigh); 308 lfloghigh = MAX(index - 1, lfloghigh);
309 } 309 }
310 /* 310 /*
311 * Using the high stale entry. 311 * Using the high stale entry.
312 * Shift entries down toward the stale slot. 312 * Shift entries down toward the stale slot.
313 */ 313 */
314 else { 314 else {
315 ASSERT(INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) == 315 ASSERT(INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) ==
316 XFS_DIR2_NULL_DATAPTR); 316 XFS_DIR2_NULL_DATAPTR);
317 ASSERT(highstale - index >= 0); 317 ASSERT(highstale - index >= 0);
318 if (highstale - index > 0) 318 if (highstale - index > 0)
319 memmove(&leaf->ents[index + 1], 319 memmove(&leaf->ents[index + 1],
320 &leaf->ents[index], 320 &leaf->ents[index],
321 (highstale - index) * sizeof(*lep)); 321 (highstale - index) * sizeof(*lep));
322 lep = &leaf->ents[index]; 322 lep = &leaf->ents[index];
323 lfloglow = MIN(index, lfloglow); 323 lfloglow = MIN(index, lfloglow);
324 lfloghigh = MAX(highstale, lfloghigh); 324 lfloghigh = MAX(highstale, lfloghigh);
325 } 325 }
326 INT_MOD(leaf->hdr.stale, ARCH_CONVERT, -1); 326 INT_MOD(leaf->hdr.stale, ARCH_CONVERT, -1);
327 } 327 }
328 /* 328 /*
329 * Insert the new entry, log everything. 329 * Insert the new entry, log everything.
330 */ 330 */
331 INT_SET(lep->hashval, ARCH_CONVERT, args->hashval); 331 INT_SET(lep->hashval, ARCH_CONVERT, args->hashval);
332 INT_SET(lep->address, ARCH_CONVERT, XFS_DIR2_DB_OFF_TO_DATAPTR(mp, args->blkno, args->index)); 332 INT_SET(lep->address, ARCH_CONVERT, XFS_DIR2_DB_OFF_TO_DATAPTR(mp, args->blkno, args->index));
333 xfs_dir2_leaf_log_header(tp, bp); 333 xfs_dir2_leaf_log_header(tp, bp);
334 xfs_dir2_leaf_log_ents(tp, bp, lfloglow, lfloghigh); 334 xfs_dir2_leaf_log_ents(tp, bp, lfloglow, lfloghigh);
335 xfs_dir2_leafn_check(dp, bp); 335 xfs_dir2_leafn_check(dp, bp);
336 return 0; 336 return 0;
337 } 337 }
338 338
339 #ifdef DEBUG 339 #ifdef DEBUG
340 /* 340 /*
341 * Check internal consistency of a leafn block. 341 * Check internal consistency of a leafn block.
342 */ 342 */
343 void 343 void
344 xfs_dir2_leafn_check( 344 xfs_dir2_leafn_check(
345 xfs_inode_t *dp, /* incore directory inode */ 345 xfs_inode_t *dp, /* incore directory inode */
346 xfs_dabuf_t *bp) /* leaf buffer */ 346 xfs_dabuf_t *bp) /* leaf buffer */
347 { 347 {
348 int i; /* leaf index */ 348 int i; /* leaf index */
349 xfs_dir2_leaf_t *leaf; /* leaf structure */ 349 xfs_dir2_leaf_t *leaf; /* leaf structure */
350 xfs_mount_t *mp; /* filesystem mount point */ 350 xfs_mount_t *mp; /* filesystem mount point */
351 int stale; /* count of stale leaves */ 351 int stale; /* count of stale leaves */
352 352
353 leaf = bp->data; 353 leaf = bp->data;
354 mp = dp->i_mount; 354 mp = dp->i_mount;
355 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); 355 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
356 ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) <= XFS_DIR2_MAX_LEAF_ENTS(mp)); 356 ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) <= XFS_DIR2_MAX_LEAF_ENTS(mp));
357 for (i = stale = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); i++) { 357 for (i = stale = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); i++) {
358 if (i + 1 < INT_GET(leaf->hdr.count, ARCH_CONVERT)) { 358 if (i + 1 < INT_GET(leaf->hdr.count, ARCH_CONVERT)) {
359 ASSERT(INT_GET(leaf->ents[i].hashval, ARCH_CONVERT) <= 359 ASSERT(INT_GET(leaf->ents[i].hashval, ARCH_CONVERT) <=
360 INT_GET(leaf->ents[i + 1].hashval, ARCH_CONVERT)); 360 INT_GET(leaf->ents[i + 1].hashval, ARCH_CONVERT));
361 } 361 }
362 if (INT_GET(leaf->ents[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) 362 if (INT_GET(leaf->ents[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
363 stale++; 363 stale++;
364 } 364 }
365 ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) == stale); 365 ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) == stale);
366 } 366 }
367 #endif /* DEBUG */ 367 #endif /* DEBUG */
368 368
369 /* 369 /*
370 * Return the last hash value in the leaf. 370 * Return the last hash value in the leaf.
371 * Stale entries are ok. 371 * Stale entries are ok.
372 */ 372 */
373 xfs_dahash_t /* hash value */ 373 xfs_dahash_t /* hash value */
374 xfs_dir2_leafn_lasthash( 374 xfs_dir2_leafn_lasthash(
375 xfs_dabuf_t *bp, /* leaf buffer */ 375 xfs_dabuf_t *bp, /* leaf buffer */
376 int *count) /* count of entries in leaf */ 376 int *count) /* count of entries in leaf */
377 { 377 {
378 xfs_dir2_leaf_t *leaf; /* leaf structure */ 378 xfs_dir2_leaf_t *leaf; /* leaf structure */
379 379
380 leaf = bp->data; 380 leaf = bp->data;
381 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); 381 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
382 if (count) 382 if (count)
383 *count = INT_GET(leaf->hdr.count, ARCH_CONVERT); 383 *count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
384 if (!leaf->hdr.count) 384 if (!leaf->hdr.count)
385 return 0; 385 return 0;
386 return INT_GET(leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT); 386 return INT_GET(leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT);
387 } 387 }
388 388
389 /* 389 /*
390 * Look up a leaf entry in a node-format leaf block. 390 * Look up a leaf entry in a node-format leaf block.
391 * If this is an addname then the extrablk in state is a freespace block, 391 * If this is an addname then the extrablk in state is a freespace block,
392 * otherwise it's a data block. 392 * otherwise it's a data block.
393 */ 393 */
394 int 394 int
395 xfs_dir2_leafn_lookup_int( 395 xfs_dir2_leafn_lookup_int(
396 xfs_dabuf_t *bp, /* leaf buffer */ 396 xfs_dabuf_t *bp, /* leaf buffer */
397 xfs_da_args_t *args, /* operation arguments */ 397 xfs_da_args_t *args, /* operation arguments */
398 int *indexp, /* out: leaf entry index */ 398 int *indexp, /* out: leaf entry index */
399 xfs_da_state_t *state) /* state to fill in */ 399 xfs_da_state_t *state) /* state to fill in */
400 { 400 {
401 xfs_dabuf_t *curbp; /* current data/free buffer */ 401 xfs_dabuf_t *curbp; /* current data/free buffer */
402 xfs_dir2_db_t curdb; /* current data block number */ 402 xfs_dir2_db_t curdb; /* current data block number */
403 xfs_dir2_db_t curfdb; /* current free block number */ 403 xfs_dir2_db_t curfdb; /* current free block number */
404 xfs_dir2_data_entry_t *dep; /* data block entry */ 404 xfs_dir2_data_entry_t *dep; /* data block entry */
405 xfs_inode_t *dp; /* incore directory inode */ 405 xfs_inode_t *dp; /* incore directory inode */
406 int error; /* error return value */ 406 int error; /* error return value */
407 int fi; /* free entry index */ 407 int fi; /* free entry index */
408 xfs_dir2_free_t *free=NULL; /* free block structure */ 408 xfs_dir2_free_t *free=NULL; /* free block structure */
409 int index; /* leaf entry index */ 409 int index; /* leaf entry index */
410 xfs_dir2_leaf_t *leaf; /* leaf structure */ 410 xfs_dir2_leaf_t *leaf; /* leaf structure */
411 int length=0; /* length of new data entry */ 411 int length=0; /* length of new data entry */
412 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 412 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
413 xfs_mount_t *mp; /* filesystem mount point */ 413 xfs_mount_t *mp; /* filesystem mount point */
414 xfs_dir2_db_t newdb; /* new data block number */ 414 xfs_dir2_db_t newdb; /* new data block number */
415 xfs_dir2_db_t newfdb; /* new free block number */ 415 xfs_dir2_db_t newfdb; /* new free block number */
416 xfs_trans_t *tp; /* transaction pointer */ 416 xfs_trans_t *tp; /* transaction pointer */
417 417
418 dp = args->dp; 418 dp = args->dp;
419 tp = args->trans; 419 tp = args->trans;
420 mp = dp->i_mount; 420 mp = dp->i_mount;
421 leaf = bp->data; 421 leaf = bp->data;
422 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); 422 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
423 #ifdef __KERNEL__ 423 #ifdef __KERNEL__
424 ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) > 0); 424 ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) > 0);
425 #endif 425 #endif
426 xfs_dir2_leafn_check(dp, bp); 426 xfs_dir2_leafn_check(dp, bp);
427 /* 427 /*
428 * Look up the hash value in the leaf entries. 428 * Look up the hash value in the leaf entries.
429 */ 429 */
430 index = xfs_dir2_leaf_search_hash(args, bp); 430 index = xfs_dir2_leaf_search_hash(args, bp);
431 /* 431 /*
432 * Do we have a buffer coming in? 432 * Do we have a buffer coming in?
433 */ 433 */
434 if (state->extravalid) 434 if (state->extravalid)
435 curbp = state->extrablk.bp; 435 curbp = state->extrablk.bp;
436 else 436 else
437 curbp = NULL; 437 curbp = NULL;
438 /* 438 /*
439 * For addname, it's a free block buffer, get the block number. 439 * For addname, it's a free block buffer, get the block number.
440 */ 440 */
441 if (args->addname) { 441 if (args->addname) {
442 curfdb = curbp ? state->extrablk.blkno : -1; 442 curfdb = curbp ? state->extrablk.blkno : -1;
443 curdb = -1; 443 curdb = -1;
444 length = XFS_DIR2_DATA_ENTSIZE(args->namelen); 444 length = XFS_DIR2_DATA_ENTSIZE(args->namelen);
445 if ((free = (curbp ? curbp->data : NULL))) 445 if ((free = (curbp ? curbp->data : NULL)))
446 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); 446 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
447 } 447 }
448 /* 448 /*
449 * For others, it's a data block buffer, get the block number. 449 * For others, it's a data block buffer, get the block number.
450 */ 450 */
451 else { 451 else {
452 curfdb = -1; 452 curfdb = -1;
453 curdb = curbp ? state->extrablk.blkno : -1; 453 curdb = curbp ? state->extrablk.blkno : -1;
454 } 454 }
455 /* 455 /*
456 * Loop over leaf entries with the right hash value. 456 * Loop over leaf entries with the right hash value.
457 */ 457 */
458 for (lep = &leaf->ents[index]; 458 for (lep = &leaf->ents[index];
459 index < INT_GET(leaf->hdr.count, ARCH_CONVERT) && INT_GET(lep->hashval, ARCH_CONVERT) == args->hashval; 459 index < INT_GET(leaf->hdr.count, ARCH_CONVERT) && INT_GET(lep->hashval, ARCH_CONVERT) == args->hashval;
460 lep++, index++) { 460 lep++, index++) {
461 /* 461 /*
462 * Skip stale leaf entries. 462 * Skip stale leaf entries.
463 */ 463 */
464 if (INT_GET(lep->address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) 464 if (INT_GET(lep->address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
465 continue; 465 continue;
466 /* 466 /*
467 * Pull the data block number from the entry. 467 * Pull the data block number from the entry.
468 */ 468 */
469 newdb = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT)); 469 newdb = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT));
470 /* 470 /*
471 * For addname, we're looking for a place to put the new entry. 471 * For addname, we're looking for a place to put the new entry.
472 * We want to use a data block with an entry of equal 472 * We want to use a data block with an entry of equal
473 * hash value to ours if there is one with room. 473 * hash value to ours if there is one with room.
474 */ 474 */
475 if (args->addname) { 475 if (args->addname) {
476 /* 476 /*
477 * If this block isn't the data block we already have 477 * If this block isn't the data block we already have
478 * in hand, take a look at it. 478 * in hand, take a look at it.
479 */ 479 */
480 if (newdb != curdb) { 480 if (newdb != curdb) {
481 curdb = newdb; 481 curdb = newdb;
482 /* 482 /*
483 * Convert the data block to the free block 483 * Convert the data block to the free block
484 * holding its freespace information. 484 * holding its freespace information.
485 */ 485 */
486 newfdb = XFS_DIR2_DB_TO_FDB(mp, newdb); 486 newfdb = XFS_DIR2_DB_TO_FDB(mp, newdb);
487 /* 487 /*
488 * If it's not the one we have in hand, 488 * If it's not the one we have in hand,
489 * read it in. 489 * read it in.
490 */ 490 */
491 if (newfdb != curfdb) { 491 if (newfdb != curfdb) {
492 /* 492 /*
493 * If we had one before, drop it. 493 * If we had one before, drop it.
494 */ 494 */
495 if (curbp) 495 if (curbp)
496 xfs_da_brelse(tp, curbp); 496 xfs_da_brelse(tp, curbp);
497 /* 497 /*
498 * Read the free block. 498 * Read the free block.
499 */ 499 */
500 if ((error = xfs_da_read_buf(tp, dp, 500 if ((error = xfs_da_read_buf(tp, dp,
501 XFS_DIR2_DB_TO_DA(mp, 501 XFS_DIR2_DB_TO_DA(mp,
502 newfdb), 502 newfdb),
503 -1, &curbp, 503 -1, &curbp,
504 XFS_DATA_FORK))) { 504 XFS_DATA_FORK))) {
505 return error; 505 return error;
506 } 506 }
507 curfdb = newfdb; 507 curfdb = newfdb;
508 free = curbp->data; 508 free = curbp->data;
509 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == 509 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) ==
510 XFS_DIR2_FREE_MAGIC); 510 XFS_DIR2_FREE_MAGIC);
511 ASSERT((INT_GET(free->hdr.firstdb, ARCH_CONVERT) % 511 ASSERT((INT_GET(free->hdr.firstdb, ARCH_CONVERT) %
512 XFS_DIR2_MAX_FREE_BESTS(mp)) == 512 XFS_DIR2_MAX_FREE_BESTS(mp)) ==
513 0); 513 0);
514 ASSERT(INT_GET(free->hdr.firstdb, ARCH_CONVERT) <= curdb); 514 ASSERT(INT_GET(free->hdr.firstdb, ARCH_CONVERT) <= curdb);
515 ASSERT(curdb < 515 ASSERT(curdb <
516 INT_GET(free->hdr.firstdb, ARCH_CONVERT) + 516 INT_GET(free->hdr.firstdb, ARCH_CONVERT) +
517 INT_GET(free->hdr.nvalid, ARCH_CONVERT)); 517 INT_GET(free->hdr.nvalid, ARCH_CONVERT));
518 } 518 }
519 /* 519 /*
520 * Get the index for our entry. 520 * Get the index for our entry.
521 */ 521 */
522 fi = XFS_DIR2_DB_TO_FDINDEX(mp, curdb); 522 fi = XFS_DIR2_DB_TO_FDINDEX(mp, curdb);
523 /* 523 /*
524 * If it has room, return it. 524 * If it has room, return it.
525 */ 525 */
526 if (unlikely(INT_GET(free->bests[fi], ARCH_CONVERT) == NULLDATAOFF)) { 526 if (unlikely(INT_GET(free->bests[fi], ARCH_CONVERT) == NULLDATAOFF)) {
527 XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int", 527 XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int",
528 XFS_ERRLEVEL_LOW, mp); 528 XFS_ERRLEVEL_LOW, mp);
529 return XFS_ERROR(EFSCORRUPTED); 529 return XFS_ERROR(EFSCORRUPTED);
530 } 530 }
531 if (INT_GET(free->bests[fi], ARCH_CONVERT) >= length) { 531 if (INT_GET(free->bests[fi], ARCH_CONVERT) >= length) {
532 *indexp = index; 532 *indexp = index;
533 state->extravalid = 1; 533 state->extravalid = 1;
534 state->extrablk.bp = curbp; 534 state->extrablk.bp = curbp;
535 state->extrablk.blkno = curfdb; 535 state->extrablk.blkno = curfdb;
536 state->extrablk.index = fi; 536 state->extrablk.index = fi;
537 state->extrablk.magic = 537 state->extrablk.magic =
538 XFS_DIR2_FREE_MAGIC; 538 XFS_DIR2_FREE_MAGIC;
539 ASSERT(args->oknoent); 539 ASSERT(args->oknoent);
540 return XFS_ERROR(ENOENT); 540 return XFS_ERROR(ENOENT);
541 } 541 }
542 } 542 }
543 } 543 }
544 /* 544 /*
545 * Not adding a new entry, so we really want to find 545 * Not adding a new entry, so we really want to find
546 * the name given to us. 546 * the name given to us.
547 */ 547 */
548 else { 548 else {
549 /* 549 /*
550 * If it's a different data block, go get it. 550 * If it's a different data block, go get it.
551 */ 551 */
552 if (newdb != curdb) { 552 if (newdb != curdb) {
553 /* 553 /*
554 * If we had a block before, drop it. 554 * If we had a block before, drop it.
555 */ 555 */
556 if (curbp) 556 if (curbp)
557 xfs_da_brelse(tp, curbp); 557 xfs_da_brelse(tp, curbp);
558 /* 558 /*
559 * Read the data block. 559 * Read the data block.
560 */ 560 */
561 if ((error = 561 if ((error =
562 xfs_da_read_buf(tp, dp, 562 xfs_da_read_buf(tp, dp,
563 XFS_DIR2_DB_TO_DA(mp, newdb), -1, 563 XFS_DIR2_DB_TO_DA(mp, newdb), -1,
564 &curbp, XFS_DATA_FORK))) { 564 &curbp, XFS_DATA_FORK))) {
565 return error; 565 return error;
566 } 566 }
567 xfs_dir2_data_check(dp, curbp); 567 xfs_dir2_data_check(dp, curbp);
568 curdb = newdb; 568 curdb = newdb;
569 } 569 }
570 /* 570 /*
571 * Point to the data entry. 571 * Point to the data entry.
572 */ 572 */
573 dep = (xfs_dir2_data_entry_t *) 573 dep = (xfs_dir2_data_entry_t *)
574 ((char *)curbp->data + 574 ((char *)curbp->data +
575 XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(lep->address, ARCH_CONVERT))); 575 XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(lep->address, ARCH_CONVERT)));
576 /* 576 /*
577 * Compare the entry, return it if it matches. 577 * Compare the entry, return it if it matches.
578 */ 578 */
579 if (dep->namelen == args->namelen && 579 if (dep->namelen == args->namelen &&
580 dep->name[0] == args->name[0] && 580 dep->name[0] == args->name[0] &&
581 memcmp(dep->name, args->name, args->namelen) == 0) { 581 memcmp(dep->name, args->name, args->namelen) == 0) {
582 args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); 582 args->inumber = INT_GET(dep->inumber, ARCH_CONVERT);
583 *indexp = index; 583 *indexp = index;
584 state->extravalid = 1; 584 state->extravalid = 1;
585 state->extrablk.bp = curbp; 585 state->extrablk.bp = curbp;
586 state->extrablk.blkno = curdb; 586 state->extrablk.blkno = curdb;
587 state->extrablk.index = 587 state->extrablk.index =
588 (int)((char *)dep - 588 (int)((char *)dep -
589 (char *)curbp->data); 589 (char *)curbp->data);
590 state->extrablk.magic = XFS_DIR2_DATA_MAGIC; 590 state->extrablk.magic = XFS_DIR2_DATA_MAGIC;
591 return XFS_ERROR(EEXIST); 591 return XFS_ERROR(EEXIST);
592 } 592 }
593 } 593 }
594 } 594 }
595 /* 595 /*
596 * Didn't find a match. 596 * Didn't find a match.
597 * If we are holding a buffer, give it back in case our caller 597 * If we are holding a buffer, give it back in case our caller
598 * finds it useful. 598 * finds it useful.
599 */ 599 */
600 if ((state->extravalid = (curbp != NULL))) { 600 if ((state->extravalid = (curbp != NULL))) {
601 state->extrablk.bp = curbp; 601 state->extrablk.bp = curbp;
602 state->extrablk.index = -1; 602 state->extrablk.index = -1;
603 /* 603 /*
604 * For addname, giving back a free block. 604 * For addname, giving back a free block.
605 */ 605 */
606 if (args->addname) { 606 if (args->addname) {
607 state->extrablk.blkno = curfdb; 607 state->extrablk.blkno = curfdb;
608 state->extrablk.magic = XFS_DIR2_FREE_MAGIC; 608 state->extrablk.magic = XFS_DIR2_FREE_MAGIC;
609 } 609 }
610 /* 610 /*
611 * For other callers, giving back a data block. 611 * For other callers, giving back a data block.
612 */ 612 */
613 else { 613 else {
614 state->extrablk.blkno = curdb; 614 state->extrablk.blkno = curdb;
615 state->extrablk.magic = XFS_DIR2_DATA_MAGIC; 615 state->extrablk.magic = XFS_DIR2_DATA_MAGIC;
616 } 616 }
617 } 617 }
618 /* 618 /*
619 * Return the final index, that will be the insertion point. 619 * Return the final index, that will be the insertion point.
620 */ 620 */
621 *indexp = index; 621 *indexp = index;
622 ASSERT(index == INT_GET(leaf->hdr.count, ARCH_CONVERT) || args->oknoent); 622 ASSERT(index == INT_GET(leaf->hdr.count, ARCH_CONVERT) || args->oknoent);
623 return XFS_ERROR(ENOENT); 623 return XFS_ERROR(ENOENT);
624 } 624 }
625 625
626 /* 626 /*
627 * Move count leaf entries from source to destination leaf. 627 * Move count leaf entries from source to destination leaf.
628 * Log entries and headers. Stale entries are preserved. 628 * Log entries and headers. Stale entries are preserved.
629 */ 629 */
630 static void 630 static void
631 xfs_dir2_leafn_moveents( 631 xfs_dir2_leafn_moveents(
632 xfs_da_args_t *args, /* operation arguments */ 632 xfs_da_args_t *args, /* operation arguments */
633 xfs_dabuf_t *bp_s, /* source leaf buffer */ 633 xfs_dabuf_t *bp_s, /* source leaf buffer */
634 int start_s, /* source leaf index */ 634 int start_s, /* source leaf index */
635 xfs_dabuf_t *bp_d, /* destination leaf buffer */ 635 xfs_dabuf_t *bp_d, /* destination leaf buffer */
636 int start_d, /* destination leaf index */ 636 int start_d, /* destination leaf index */
637 int count) /* count of leaves to copy */ 637 int count) /* count of leaves to copy */
638 { 638 {
639 xfs_dir2_leaf_t *leaf_d; /* destination leaf structure */ 639 xfs_dir2_leaf_t *leaf_d; /* destination leaf structure */
640 xfs_dir2_leaf_t *leaf_s; /* source leaf structure */ 640 xfs_dir2_leaf_t *leaf_s; /* source leaf structure */
641 int stale; /* count stale leaves copied */ 641 int stale; /* count stale leaves copied */
642 xfs_trans_t *tp; /* transaction pointer */ 642 xfs_trans_t *tp; /* transaction pointer */
643 643
644 xfs_dir2_trace_args_bibii("leafn_moveents", args, bp_s, start_s, bp_d, 644 xfs_dir2_trace_args_bibii("leafn_moveents", args, bp_s, start_s, bp_d,
645 start_d, count); 645 start_d, count);
646 /* 646 /*
647 * Silently return if nothing to do. 647 * Silently return if nothing to do.
648 */ 648 */
649 if (count == 0) { 649 if (count == 0) {
650 return; 650 return;
651 } 651 }
652 tp = args->trans; 652 tp = args->trans;
653 leaf_s = bp_s->data; 653 leaf_s = bp_s->data;
654 leaf_d = bp_d->data; 654 leaf_d = bp_d->data;
655 /* 655 /*
656 * If the destination index is not the end of the current 656 * If the destination index is not the end of the current
657 * destination leaf entries, open up a hole in the destination 657 * destination leaf entries, open up a hole in the destination
658 * to hold the new entries. 658 * to hold the new entries.
659 */ 659 */
660 if (start_d < INT_GET(leaf_d->hdr.count, ARCH_CONVERT)) { 660 if (start_d < INT_GET(leaf_d->hdr.count, ARCH_CONVERT)) {
661 memmove(&leaf_d->ents[start_d + count], &leaf_d->ents[start_d], 661 memmove(&leaf_d->ents[start_d + count], &leaf_d->ents[start_d],
662 (INT_GET(leaf_d->hdr.count, ARCH_CONVERT) - start_d) * 662 (INT_GET(leaf_d->hdr.count, ARCH_CONVERT) - start_d) *
663 sizeof(xfs_dir2_leaf_entry_t)); 663 sizeof(xfs_dir2_leaf_entry_t));
664 xfs_dir2_leaf_log_ents(tp, bp_d, start_d + count, 664 xfs_dir2_leaf_log_ents(tp, bp_d, start_d + count,
665 count + INT_GET(leaf_d->hdr.count, ARCH_CONVERT) - 1); 665 count + INT_GET(leaf_d->hdr.count, ARCH_CONVERT) - 1);
666 } 666 }
667 /* 667 /*
668 * If the source has stale leaves, count the ones in the copy range 668 * If the source has stale leaves, count the ones in the copy range
669 * so we can update the header correctly. 669 * so we can update the header correctly.
670 */ 670 */
671 if (leaf_s->hdr.stale) { 671 if (leaf_s->hdr.stale) {
672 int i; /* temp leaf index */ 672 int i; /* temp leaf index */
673 673
674 for (i = start_s, stale = 0; i < start_s + count; i++) { 674 for (i = start_s, stale = 0; i < start_s + count; i++) {
675 if (INT_GET(leaf_s->ents[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) 675 if (INT_GET(leaf_s->ents[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
676 stale++; 676 stale++;
677 } 677 }
678 } else 678 } else
679 stale = 0; 679 stale = 0;
680 /* 680 /*
681 * Copy the leaf entries from source to destination. 681 * Copy the leaf entries from source to destination.
682 */ 682 */
683 memcpy(&leaf_d->ents[start_d], &leaf_s->ents[start_s], 683 memcpy(&leaf_d->ents[start_d], &leaf_s->ents[start_s],
684 count * sizeof(xfs_dir2_leaf_entry_t)); 684 count * sizeof(xfs_dir2_leaf_entry_t));
685 xfs_dir2_leaf_log_ents(tp, bp_d, start_d, start_d + count - 1); 685 xfs_dir2_leaf_log_ents(tp, bp_d, start_d, start_d + count - 1);
686 /* 686 /*
687 * If there are source entries after the ones we copied, 687 * If there are source entries after the ones we copied,
688 * delete the ones we copied by sliding the next ones down. 688 * delete the ones we copied by sliding the next ones down.
689 */ 689 */
690 if (start_s + count < INT_GET(leaf_s->hdr.count, ARCH_CONVERT)) { 690 if (start_s + count < INT_GET(leaf_s->hdr.count, ARCH_CONVERT)) {
691 memmove(&leaf_s->ents[start_s], &leaf_s->ents[start_s + count], 691 memmove(&leaf_s->ents[start_s], &leaf_s->ents[start_s + count],
692 count * sizeof(xfs_dir2_leaf_entry_t)); 692 count * sizeof(xfs_dir2_leaf_entry_t));
693 xfs_dir2_leaf_log_ents(tp, bp_s, start_s, start_s + count - 1); 693 xfs_dir2_leaf_log_ents(tp, bp_s, start_s, start_s + count - 1);
694 } 694 }
695 /* 695 /*
696 * Update the headers and log them. 696 * Update the headers and log them.
697 */ 697 */
698 INT_MOD(leaf_s->hdr.count, ARCH_CONVERT, -(count)); 698 INT_MOD(leaf_s->hdr.count, ARCH_CONVERT, -(count));
699 INT_MOD(leaf_s->hdr.stale, ARCH_CONVERT, -(stale)); 699 INT_MOD(leaf_s->hdr.stale, ARCH_CONVERT, -(stale));
700 INT_MOD(leaf_d->hdr.count, ARCH_CONVERT, count); 700 INT_MOD(leaf_d->hdr.count, ARCH_CONVERT, count);
701 INT_MOD(leaf_d->hdr.stale, ARCH_CONVERT, stale); 701 INT_MOD(leaf_d->hdr.stale, ARCH_CONVERT, stale);
702 xfs_dir2_leaf_log_header(tp, bp_s); 702 xfs_dir2_leaf_log_header(tp, bp_s);
703 xfs_dir2_leaf_log_header(tp, bp_d); 703 xfs_dir2_leaf_log_header(tp, bp_d);
704 xfs_dir2_leafn_check(args->dp, bp_s); 704 xfs_dir2_leafn_check(args->dp, bp_s);
705 xfs_dir2_leafn_check(args->dp, bp_d); 705 xfs_dir2_leafn_check(args->dp, bp_d);
706 } 706 }
707 707
708 /* 708 /*
709 * Determine the sort order of two leaf blocks. 709 * Determine the sort order of two leaf blocks.
710 * Returns 1 if both are valid and leaf2 should be before leaf1, else 0. 710 * Returns 1 if both are valid and leaf2 should be before leaf1, else 0.
711 */ 711 */
712 int /* sort order */ 712 int /* sort order */
713 xfs_dir2_leafn_order( 713 xfs_dir2_leafn_order(
714 xfs_dabuf_t *leaf1_bp, /* leaf1 buffer */ 714 xfs_dabuf_t *leaf1_bp, /* leaf1 buffer */
715 xfs_dabuf_t *leaf2_bp) /* leaf2 buffer */ 715 xfs_dabuf_t *leaf2_bp) /* leaf2 buffer */
716 { 716 {
717 xfs_dir2_leaf_t *leaf1; /* leaf1 structure */ 717 xfs_dir2_leaf_t *leaf1; /* leaf1 structure */
718 xfs_dir2_leaf_t *leaf2; /* leaf2 structure */ 718 xfs_dir2_leaf_t *leaf2; /* leaf2 structure */
719 719
720 leaf1 = leaf1_bp->data; 720 leaf1 = leaf1_bp->data;
721 leaf2 = leaf2_bp->data; 721 leaf2 = leaf2_bp->data;
722 ASSERT(INT_GET(leaf1->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); 722 ASSERT(INT_GET(leaf1->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
723 ASSERT(INT_GET(leaf2->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); 723 ASSERT(INT_GET(leaf2->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
724 if (INT_GET(leaf1->hdr.count, ARCH_CONVERT) > 0 && 724 if (INT_GET(leaf1->hdr.count, ARCH_CONVERT) > 0 &&
725 INT_GET(leaf2->hdr.count, ARCH_CONVERT) > 0 && 725 INT_GET(leaf2->hdr.count, ARCH_CONVERT) > 0 &&
726 (INT_GET(leaf2->ents[0].hashval, ARCH_CONVERT) < INT_GET(leaf1->ents[0].hashval, ARCH_CONVERT) || 726 (INT_GET(leaf2->ents[0].hashval, ARCH_CONVERT) < INT_GET(leaf1->ents[0].hashval, ARCH_CONVERT) ||
727 INT_GET(leaf2->ents[INT_GET(leaf2->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT) < 727 INT_GET(leaf2->ents[INT_GET(leaf2->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT) <
728 INT_GET(leaf1->ents[INT_GET(leaf1->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT))) 728 INT_GET(leaf1->ents[INT_GET(leaf1->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT)))
729 return 1; 729 return 1;
730 return 0; 730 return 0;
731 } 731 }
732 732
733 /* 733 /*
734 * Rebalance leaf entries between two leaf blocks. 734 * Rebalance leaf entries between two leaf blocks.
735 * This is actually only called when the second block is new, 735 * This is actually only called when the second block is new,
736 * though the code deals with the general case. 736 * though the code deals with the general case.
737 * A new entry will be inserted in one of the blocks, and that 737 * A new entry will be inserted in one of the blocks, and that
738 * entry is taken into account when balancing. 738 * entry is taken into account when balancing.
739 */ 739 */
740 static void 740 static void
741 xfs_dir2_leafn_rebalance( 741 xfs_dir2_leafn_rebalance(
742 xfs_da_state_t *state, /* btree cursor */ 742 xfs_da_state_t *state, /* btree cursor */
743 xfs_da_state_blk_t *blk1, /* first btree block */ 743 xfs_da_state_blk_t *blk1, /* first btree block */
744 xfs_da_state_blk_t *blk2) /* second btree block */ 744 xfs_da_state_blk_t *blk2) /* second btree block */
745 { 745 {
746 xfs_da_args_t *args; /* operation arguments */ 746 xfs_da_args_t *args; /* operation arguments */
747 int count; /* count (& direction) leaves */ 747 int count; /* count (& direction) leaves */
748 int isleft; /* new goes in left leaf */ 748 int isleft; /* new goes in left leaf */
749 xfs_dir2_leaf_t *leaf1; /* first leaf structure */ 749 xfs_dir2_leaf_t *leaf1; /* first leaf structure */
750 xfs_dir2_leaf_t *leaf2; /* second leaf structure */ 750 xfs_dir2_leaf_t *leaf2; /* second leaf structure */
751 int mid; /* midpoint leaf index */ 751 int mid; /* midpoint leaf index */
752 #ifdef DEBUG 752 #ifdef DEBUG
753 int oldstale; /* old count of stale leaves */ 753 int oldstale; /* old count of stale leaves */
754 #endif 754 #endif
755 int oldsum; /* old total leaf count */ 755 int oldsum; /* old total leaf count */
756 int swap; /* swapped leaf blocks */ 756 int swap; /* swapped leaf blocks */
757 757
758 args = state->args; 758 args = state->args;
759 /* 759 /*
760 * If the block order is wrong, swap the arguments. 760 * If the block order is wrong, swap the arguments.
761 */ 761 */
762 if ((swap = xfs_dir2_leafn_order(blk1->bp, blk2->bp))) { 762 if ((swap = xfs_dir2_leafn_order(blk1->bp, blk2->bp))) {
763 xfs_da_state_blk_t *tmp; /* temp for block swap */ 763 xfs_da_state_blk_t *tmp; /* temp for block swap */
764 764
765 tmp = blk1; 765 tmp = blk1;
766 blk1 = blk2; 766 blk1 = blk2;
767 blk2 = tmp; 767 blk2 = tmp;
768 } 768 }
769 leaf1 = blk1->bp->data; 769 leaf1 = blk1->bp->data;
770 leaf2 = blk2->bp->data; 770 leaf2 = blk2->bp->data;
771 oldsum = INT_GET(leaf1->hdr.count, ARCH_CONVERT) + INT_GET(leaf2->hdr.count, ARCH_CONVERT); 771 oldsum = INT_GET(leaf1->hdr.count, ARCH_CONVERT) + INT_GET(leaf2->hdr.count, ARCH_CONVERT);
772 #ifdef DEBUG 772 #ifdef DEBUG
773 oldstale = INT_GET(leaf1->hdr.stale, ARCH_CONVERT) + INT_GET(leaf2->hdr.stale, ARCH_CONVERT); 773 oldstale = INT_GET(leaf1->hdr.stale, ARCH_CONVERT) + INT_GET(leaf2->hdr.stale, ARCH_CONVERT);
774 #endif 774 #endif
775 mid = oldsum >> 1; 775 mid = oldsum >> 1;
776 /* 776 /*
777 * If the old leaf count was odd then the new one will be even, 777 * If the old leaf count was odd then the new one will be even,
778 * so we need to divide the new count evenly. 778 * so we need to divide the new count evenly.
779 */ 779 */
780 if (oldsum & 1) { 780 if (oldsum & 1) {
781 xfs_dahash_t midhash; /* middle entry hash value */ 781 xfs_dahash_t midhash; /* middle entry hash value */
782 782
783 if (mid >= INT_GET(leaf1->hdr.count, ARCH_CONVERT)) 783 if (mid >= INT_GET(leaf1->hdr.count, ARCH_CONVERT))
784 midhash = INT_GET(leaf2->ents[mid - INT_GET(leaf1->hdr.count, ARCH_CONVERT)].hashval, ARCH_CONVERT); 784 midhash = INT_GET(leaf2->ents[mid - INT_GET(leaf1->hdr.count, ARCH_CONVERT)].hashval, ARCH_CONVERT);
785 else 785 else
786 midhash = INT_GET(leaf1->ents[mid].hashval, ARCH_CONVERT); 786 midhash = INT_GET(leaf1->ents[mid].hashval, ARCH_CONVERT);
787 isleft = args->hashval <= midhash; 787 isleft = args->hashval <= midhash;
788 } 788 }
789 /* 789 /*
790 * If the old count is even then the new count is odd, so there's 790 * If the old count is even then the new count is odd, so there's
791 * no preferred side for the new entry. 791 * no preferred side for the new entry.
792 * Pick the left one. 792 * Pick the left one.
793 */ 793 */
794 else 794 else
795 isleft = 1; 795 isleft = 1;
796 /* 796 /*
797 * Calculate moved entry count. Positive means left-to-right, 797 * Calculate moved entry count. Positive means left-to-right,
798 * negative means right-to-left. Then move the entries. 798 * negative means right-to-left. Then move the entries.
799 */ 799 */
800 count = INT_GET(leaf1->hdr.count, ARCH_CONVERT) - mid + (isleft == 0); 800 count = INT_GET(leaf1->hdr.count, ARCH_CONVERT) - mid + (isleft == 0);
801 if (count > 0) 801 if (count > 0)
802 xfs_dir2_leafn_moveents(args, blk1->bp, 802 xfs_dir2_leafn_moveents(args, blk1->bp,
803 INT_GET(leaf1->hdr.count, ARCH_CONVERT) - count, blk2->bp, 0, count); 803 INT_GET(leaf1->hdr.count, ARCH_CONVERT) - count, blk2->bp, 0, count);
804 else if (count < 0) 804 else if (count < 0)
805 xfs_dir2_leafn_moveents(args, blk2->bp, 0, blk1->bp, 805 xfs_dir2_leafn_moveents(args, blk2->bp, 0, blk1->bp,
806 INT_GET(leaf1->hdr.count, ARCH_CONVERT), count); 806 INT_GET(leaf1->hdr.count, ARCH_CONVERT), count);
807 ASSERT(INT_GET(leaf1->hdr.count, ARCH_CONVERT) + INT_GET(leaf2->hdr.count, ARCH_CONVERT) == oldsum); 807 ASSERT(INT_GET(leaf1->hdr.count, ARCH_CONVERT) + INT_GET(leaf2->hdr.count, ARCH_CONVERT) == oldsum);
808 ASSERT(INT_GET(leaf1->hdr.stale, ARCH_CONVERT) + INT_GET(leaf2->hdr.stale, ARCH_CONVERT) == oldstale); 808 ASSERT(INT_GET(leaf1->hdr.stale, ARCH_CONVERT) + INT_GET(leaf2->hdr.stale, ARCH_CONVERT) == oldstale);
809 /* 809 /*
810 * Mark whether we're inserting into the old or new leaf. 810 * Mark whether we're inserting into the old or new leaf.
811 */ 811 */
812 if (INT_GET(leaf1->hdr.count, ARCH_CONVERT) < INT_GET(leaf2->hdr.count, ARCH_CONVERT)) 812 if (INT_GET(leaf1->hdr.count, ARCH_CONVERT) < INT_GET(leaf2->hdr.count, ARCH_CONVERT))
813 state->inleaf = swap; 813 state->inleaf = swap;
814 else if (INT_GET(leaf1->hdr.count, ARCH_CONVERT) > INT_GET(leaf2->hdr.count, ARCH_CONVERT)) 814 else if (INT_GET(leaf1->hdr.count, ARCH_CONVERT) > INT_GET(leaf2->hdr.count, ARCH_CONVERT))
815 state->inleaf = !swap; 815 state->inleaf = !swap;
816 else 816 else
817 state->inleaf = 817 state->inleaf =
818 swap ^ (blk1->index <= INT_GET(leaf1->hdr.count, ARCH_CONVERT)); 818 swap ^ (blk1->index <= INT_GET(leaf1->hdr.count, ARCH_CONVERT));
819 /* 819 /*
820 * Adjust the expected index for insertion. 820 * Adjust the expected index for insertion.
821 */ 821 */
822 if (!state->inleaf) 822 if (!state->inleaf)
823 blk2->index = blk1->index - INT_GET(leaf1->hdr.count, ARCH_CONVERT); 823 blk2->index = blk1->index - INT_GET(leaf1->hdr.count, ARCH_CONVERT);
824 824
825 /* 825 /*
826 * Finally sanity check just to make sure we are not returning a negative index 826 * Finally sanity check just to make sure we are not returning a negative index
827 */ 827 */
828 if(blk2->index < 0) { 828 if(blk2->index < 0) {
829 state->inleaf = 1; 829 state->inleaf = 1;
830 blk2->index = 0; 830 blk2->index = 0;
831 cmn_err(CE_ALERT, 831 cmn_err(CE_ALERT,
832 "xfs_dir2_leafn_rebalance: picked the wrong leaf? reverting orignal leaf: " 832 "xfs_dir2_leafn_rebalance: picked the wrong leaf? reverting orignal leaf: "
833 "blk1->index %d\n", 833 "blk1->index %d\n",
834 blk1->index); 834 blk1->index);
835 } 835 }
836 } 836 }
837 837
838 /* 838 /*
839 * Remove an entry from a node directory. 839 * Remove an entry from a node directory.
840 * This removes the leaf entry and the data entry, 840 * This removes the leaf entry and the data entry,
841 * and updates the free block if necessary. 841 * and updates the free block if necessary.
842 */ 842 */
843 static int /* error */ 843 static int /* error */
844 xfs_dir2_leafn_remove( 844 xfs_dir2_leafn_remove(
845 xfs_da_args_t *args, /* operation arguments */ 845 xfs_da_args_t *args, /* operation arguments */
846 xfs_dabuf_t *bp, /* leaf buffer */ 846 xfs_dabuf_t *bp, /* leaf buffer */
847 int index, /* leaf entry index */ 847 int index, /* leaf entry index */
848 xfs_da_state_blk_t *dblk, /* data block */ 848 xfs_da_state_blk_t *dblk, /* data block */
849 int *rval) /* resulting block needs join */ 849 int *rval) /* resulting block needs join */
850 { 850 {
851 xfs_dir2_data_t *data; /* data block structure */ 851 xfs_dir2_data_t *data; /* data block structure */
852 xfs_dir2_db_t db; /* data block number */ 852 xfs_dir2_db_t db; /* data block number */
853 xfs_dabuf_t *dbp; /* data block buffer */ 853 xfs_dabuf_t *dbp; /* data block buffer */
854 xfs_dir2_data_entry_t *dep; /* data block entry */ 854 xfs_dir2_data_entry_t *dep; /* data block entry */
855 xfs_inode_t *dp; /* incore directory inode */ 855 xfs_inode_t *dp; /* incore directory inode */
856 xfs_dir2_leaf_t *leaf; /* leaf structure */ 856 xfs_dir2_leaf_t *leaf; /* leaf structure */
857 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 857 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
858 int longest; /* longest data free entry */ 858 int longest; /* longest data free entry */
859 int off; /* data block entry offset */ 859 int off; /* data block entry offset */
860 xfs_mount_t *mp; /* filesystem mount point */ 860 xfs_mount_t *mp; /* filesystem mount point */
861 int needlog; /* need to log data header */ 861 int needlog; /* need to log data header */
862 int needscan; /* need to rescan data frees */ 862 int needscan; /* need to rescan data frees */
863 xfs_trans_t *tp; /* transaction pointer */ 863 xfs_trans_t *tp; /* transaction pointer */
864 864
865 xfs_dir2_trace_args_sb("leafn_remove", args, index, bp); 865 xfs_dir2_trace_args_sb("leafn_remove", args, index, bp);
866 dp = args->dp; 866 dp = args->dp;
867 tp = args->trans; 867 tp = args->trans;
868 mp = dp->i_mount; 868 mp = dp->i_mount;
869 leaf = bp->data; 869 leaf = bp->data;
870 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); 870 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
871 /* 871 /*
872 * Point to the entry we're removing. 872 * Point to the entry we're removing.
873 */ 873 */
874 lep = &leaf->ents[index]; 874 lep = &leaf->ents[index];
875 /* 875 /*
876 * Extract the data block and offset from the entry. 876 * Extract the data block and offset from the entry.
877 */ 877 */
878 db = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT)); 878 db = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT));
879 ASSERT(dblk->blkno == db); 879 ASSERT(dblk->blkno == db);
880 off = XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(lep->address, ARCH_CONVERT)); 880 off = XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(lep->address, ARCH_CONVERT));
881 ASSERT(dblk->index == off); 881 ASSERT(dblk->index == off);
882 /* 882 /*
883 * Kill the leaf entry by marking it stale. 883 * Kill the leaf entry by marking it stale.
884 * Log the leaf block changes. 884 * Log the leaf block changes.
885 */ 885 */
886 INT_MOD(leaf->hdr.stale, ARCH_CONVERT, +1); 886 INT_MOD(leaf->hdr.stale, ARCH_CONVERT, +1);
887 xfs_dir2_leaf_log_header(tp, bp); 887 xfs_dir2_leaf_log_header(tp, bp);
888 INT_SET(lep->address, ARCH_CONVERT, XFS_DIR2_NULL_DATAPTR); 888 INT_SET(lep->address, ARCH_CONVERT, XFS_DIR2_NULL_DATAPTR);
889 xfs_dir2_leaf_log_ents(tp, bp, index, index); 889 xfs_dir2_leaf_log_ents(tp, bp, index, index);
890 /* 890 /*
891 * Make the data entry free. Keep track of the longest freespace 891 * Make the data entry free. Keep track of the longest freespace
892 * in the data block in case it changes. 892 * in the data block in case it changes.
893 */ 893 */
894 dbp = dblk->bp; 894 dbp = dblk->bp;
895 data = dbp->data; 895 data = dbp->data;
896 dep = (xfs_dir2_data_entry_t *)((char *)data + off); 896 dep = (xfs_dir2_data_entry_t *)((char *)data + off);
897 longest = INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT); 897 longest = be16_to_cpu(data->hdr.bestfree[0].length);
898 needlog = needscan = 0; 898 needlog = needscan = 0;
899 xfs_dir2_data_make_free(tp, dbp, off, 899 xfs_dir2_data_make_free(tp, dbp, off,
900 XFS_DIR2_DATA_ENTSIZE(dep->namelen), &needlog, &needscan); 900 XFS_DIR2_DATA_ENTSIZE(dep->namelen), &needlog, &needscan);
901 /* 901 /*
902 * Rescan the data block freespaces for bestfree. 902 * Rescan the data block freespaces for bestfree.
903 * Log the data block header if needed. 903 * Log the data block header if needed.
904 */ 904 */
905 if (needscan) 905 if (needscan)
906 xfs_dir2_data_freescan(mp, data, &needlog, NULL); 906 xfs_dir2_data_freescan(mp, data, &needlog, NULL);
907 if (needlog) 907 if (needlog)
908 xfs_dir2_data_log_header(tp, dbp); 908 xfs_dir2_data_log_header(tp, dbp);
909 xfs_dir2_data_check(dp, dbp); 909 xfs_dir2_data_check(dp, dbp);
910 /* 910 /*
911 * If the longest data block freespace changes, need to update 911 * If the longest data block freespace changes, need to update
912 * the corresponding freeblock entry. 912 * the corresponding freeblock entry.
913 */ 913 */
914 if (longest < INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT)) { 914 if (longest < be16_to_cpu(data->hdr.bestfree[0].length)) {
915 int error; /* error return value */ 915 int error; /* error return value */
916 xfs_dabuf_t *fbp; /* freeblock buffer */ 916 xfs_dabuf_t *fbp; /* freeblock buffer */
917 xfs_dir2_db_t fdb; /* freeblock block number */ 917 xfs_dir2_db_t fdb; /* freeblock block number */
918 int findex; /* index in freeblock entries */ 918 int findex; /* index in freeblock entries */
919 xfs_dir2_free_t *free; /* freeblock structure */ 919 xfs_dir2_free_t *free; /* freeblock structure */
920 int logfree; /* need to log free entry */ 920 int logfree; /* need to log free entry */
921 921
922 /* 922 /*
923 * Convert the data block number to a free block, 923 * Convert the data block number to a free block,
924 * read in the free block. 924 * read in the free block.
925 */ 925 */
926 fdb = XFS_DIR2_DB_TO_FDB(mp, db); 926 fdb = XFS_DIR2_DB_TO_FDB(mp, db);
927 if ((error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, fdb), 927 if ((error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, fdb),
928 -1, &fbp, XFS_DATA_FORK))) { 928 -1, &fbp, XFS_DATA_FORK))) {
929 return error; 929 return error;
930 } 930 }
931 free = fbp->data; 931 free = fbp->data;
932 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); 932 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
933 ASSERT(INT_GET(free->hdr.firstdb, ARCH_CONVERT) == 933 ASSERT(INT_GET(free->hdr.firstdb, ARCH_CONVERT) ==
934 XFS_DIR2_MAX_FREE_BESTS(mp) * 934 XFS_DIR2_MAX_FREE_BESTS(mp) *
935 (fdb - XFS_DIR2_FREE_FIRSTDB(mp))); 935 (fdb - XFS_DIR2_FREE_FIRSTDB(mp)));
936 /* 936 /*
937 * Calculate which entry we need to fix. 937 * Calculate which entry we need to fix.
938 */ 938 */
939 findex = XFS_DIR2_DB_TO_FDINDEX(mp, db); 939 findex = XFS_DIR2_DB_TO_FDINDEX(mp, db);
940 longest = INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT); 940 longest = be16_to_cpu(data->hdr.bestfree[0].length);
941 /* 941 /*
942 * If the data block is now empty we can get rid of it 942 * If the data block is now empty we can get rid of it
943 * (usually). 943 * (usually).
944 */ 944 */
945 if (longest == mp->m_dirblksize - (uint)sizeof(data->hdr)) { 945 if (longest == mp->m_dirblksize - (uint)sizeof(data->hdr)) {
946 /* 946 /*
947 * Try to punch out the data block. 947 * Try to punch out the data block.
948 */ 948 */
949 error = xfs_dir2_shrink_inode(args, db, dbp); 949 error = xfs_dir2_shrink_inode(args, db, dbp);
950 if (error == 0) { 950 if (error == 0) {
951 dblk->bp = NULL; 951 dblk->bp = NULL;
952 data = NULL; 952 data = NULL;
953 } 953 }
954 /* 954 /*
955 * We can get ENOSPC if there's no space reservation. 955 * We can get ENOSPC if there's no space reservation.
956 * In this case just drop the buffer and some one else 956 * In this case just drop the buffer and some one else
957 * will eventually get rid of the empty block. 957 * will eventually get rid of the empty block.
958 */ 958 */
959 else if (error == ENOSPC && args->total == 0) 959 else if (error == ENOSPC && args->total == 0)
960 xfs_da_buf_done(dbp); 960 xfs_da_buf_done(dbp);
961 else 961 else
962 return error; 962 return error;
963 } 963 }
964 /* 964 /*
965 * If we got rid of the data block, we can eliminate that entry 965 * If we got rid of the data block, we can eliminate that entry
966 * in the free block. 966 * in the free block.
967 */ 967 */
968 if (data == NULL) { 968 if (data == NULL) {
969 /* 969 /*
970 * One less used entry in the free table. 970 * One less used entry in the free table.
971 */ 971 */
972 INT_MOD(free->hdr.nused, ARCH_CONVERT, -1); 972 INT_MOD(free->hdr.nused, ARCH_CONVERT, -1);
973 xfs_dir2_free_log_header(tp, fbp); 973 xfs_dir2_free_log_header(tp, fbp);
974 /* 974 /*
975 * If this was the last entry in the table, we can 975 * If this was the last entry in the table, we can
976 * trim the table size back. There might be other 976 * trim the table size back. There might be other
977 * entries at the end referring to non-existent 977 * entries at the end referring to non-existent
978 * data blocks, get those too. 978 * data blocks, get those too.
979 */ 979 */
980 if (findex == INT_GET(free->hdr.nvalid, ARCH_CONVERT) - 1) { 980 if (findex == INT_GET(free->hdr.nvalid, ARCH_CONVERT) - 1) {
981 int i; /* free entry index */ 981 int i; /* free entry index */
982 982
983 for (i = findex - 1; 983 for (i = findex - 1;
984 i >= 0 && INT_GET(free->bests[i], ARCH_CONVERT) == NULLDATAOFF; 984 i >= 0 && INT_GET(free->bests[i], ARCH_CONVERT) == NULLDATAOFF;
985 i--) 985 i--)
986 continue; 986 continue;
987 INT_SET(free->hdr.nvalid, ARCH_CONVERT, i + 1); 987 INT_SET(free->hdr.nvalid, ARCH_CONVERT, i + 1);
988 logfree = 0; 988 logfree = 0;
989 } 989 }
990 /* 990 /*
991 * Not the last entry, just punch it out. 991 * Not the last entry, just punch it out.
992 */ 992 */
993 else { 993 else {
994 INT_SET(free->bests[findex], ARCH_CONVERT, NULLDATAOFF); 994 INT_SET(free->bests[findex], ARCH_CONVERT, NULLDATAOFF);
995 logfree = 1; 995 logfree = 1;
996 } 996 }
997 /* 997 /*
998 * If there are no useful entries left in the block, 998 * If there are no useful entries left in the block,
999 * get rid of the block if we can. 999 * get rid of the block if we can.
1000 */ 1000 */
1001 if (!free->hdr.nused) { 1001 if (!free->hdr.nused) {
1002 error = xfs_dir2_shrink_inode(args, fdb, fbp); 1002 error = xfs_dir2_shrink_inode(args, fdb, fbp);
1003 if (error == 0) { 1003 if (error == 0) {
1004 fbp = NULL; 1004 fbp = NULL;
1005 logfree = 0; 1005 logfree = 0;
1006 } else if (error != ENOSPC || args->total != 0) 1006 } else if (error != ENOSPC || args->total != 0)
1007 return error; 1007 return error;
1008 /* 1008 /*
1009 * It's possible to get ENOSPC if there is no 1009 * It's possible to get ENOSPC if there is no
1010 * space reservation. In this case some one 1010 * space reservation. In this case some one
1011 * else will eventually get rid of this block. 1011 * else will eventually get rid of this block.
1012 */ 1012 */
1013 } 1013 }
1014 } 1014 }
1015 /* 1015 /*
1016 * Data block is not empty, just set the free entry to 1016 * Data block is not empty, just set the free entry to
1017 * the new value. 1017 * the new value.
1018 */ 1018 */
1019 else { 1019 else {
1020 INT_SET(free->bests[findex], ARCH_CONVERT, longest); 1020 INT_SET(free->bests[findex], ARCH_CONVERT, longest);
1021 logfree = 1; 1021 logfree = 1;
1022 } 1022 }
1023 /* 1023 /*
1024 * Log the free entry that changed, unless we got rid of it. 1024 * Log the free entry that changed, unless we got rid of it.
1025 */ 1025 */
1026 if (logfree) 1026 if (logfree)
1027 xfs_dir2_free_log_bests(tp, fbp, findex, findex); 1027 xfs_dir2_free_log_bests(tp, fbp, findex, findex);
1028 /* 1028 /*
1029 * Drop the buffer if we still have it. 1029 * Drop the buffer if we still have it.
1030 */ 1030 */
1031 if (fbp) 1031 if (fbp)
1032 xfs_da_buf_done(fbp); 1032 xfs_da_buf_done(fbp);
1033 } 1033 }
1034 xfs_dir2_leafn_check(dp, bp); 1034 xfs_dir2_leafn_check(dp, bp);
1035 /* 1035 /*
1036 * Return indication of whether this leaf block is emtpy enough 1036 * Return indication of whether this leaf block is emtpy enough
1037 * to justify trying to join it with a neighbor. 1037 * to justify trying to join it with a neighbor.
1038 */ 1038 */
1039 *rval = 1039 *rval =
1040 ((uint)sizeof(leaf->hdr) + 1040 ((uint)sizeof(leaf->hdr) +
1041 (uint)sizeof(leaf->ents[0]) * 1041 (uint)sizeof(leaf->ents[0]) *
1042 (INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT))) < 1042 (INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT))) <
1043 mp->m_dir_magicpct; 1043 mp->m_dir_magicpct;
1044 return 0; 1044 return 0;
1045 } 1045 }
1046 1046
1047 /* 1047 /*
1048 * Split the leaf entries in the old block into old and new blocks. 1048 * Split the leaf entries in the old block into old and new blocks.
1049 */ 1049 */
1050 int /* error */ 1050 int /* error */
1051 xfs_dir2_leafn_split( 1051 xfs_dir2_leafn_split(
1052 xfs_da_state_t *state, /* btree cursor */ 1052 xfs_da_state_t *state, /* btree cursor */
1053 xfs_da_state_blk_t *oldblk, /* original block */ 1053 xfs_da_state_blk_t *oldblk, /* original block */
1054 xfs_da_state_blk_t *newblk) /* newly created block */ 1054 xfs_da_state_blk_t *newblk) /* newly created block */
1055 { 1055 {
1056 xfs_da_args_t *args; /* operation arguments */ 1056 xfs_da_args_t *args; /* operation arguments */
1057 xfs_dablk_t blkno; /* new leaf block number */ 1057 xfs_dablk_t blkno; /* new leaf block number */
1058 int error; /* error return value */ 1058 int error; /* error return value */
1059 xfs_mount_t *mp; /* filesystem mount point */ 1059 xfs_mount_t *mp; /* filesystem mount point */
1060 1060
1061 /* 1061 /*
1062 * Allocate space for a new leaf node. 1062 * Allocate space for a new leaf node.
1063 */ 1063 */
1064 args = state->args; 1064 args = state->args;
1065 mp = args->dp->i_mount; 1065 mp = args->dp->i_mount;
1066 ASSERT(args != NULL); 1066 ASSERT(args != NULL);
1067 ASSERT(oldblk->magic == XFS_DIR2_LEAFN_MAGIC); 1067 ASSERT(oldblk->magic == XFS_DIR2_LEAFN_MAGIC);
1068 error = xfs_da_grow_inode(args, &blkno); 1068 error = xfs_da_grow_inode(args, &blkno);
1069 if (error) { 1069 if (error) {
1070 return error; 1070 return error;
1071 } 1071 }
1072 /* 1072 /*
1073 * Initialize the new leaf block. 1073 * Initialize the new leaf block.
1074 */ 1074 */
1075 error = xfs_dir2_leaf_init(args, XFS_DIR2_DA_TO_DB(mp, blkno), 1075 error = xfs_dir2_leaf_init(args, XFS_DIR2_DA_TO_DB(mp, blkno),
1076 &newblk->bp, XFS_DIR2_LEAFN_MAGIC); 1076 &newblk->bp, XFS_DIR2_LEAFN_MAGIC);
1077 if (error) { 1077 if (error) {
1078 return error; 1078 return error;
1079 } 1079 }
1080 newblk->blkno = blkno; 1080 newblk->blkno = blkno;
1081 newblk->magic = XFS_DIR2_LEAFN_MAGIC; 1081 newblk->magic = XFS_DIR2_LEAFN_MAGIC;
1082 /* 1082 /*
1083 * Rebalance the entries across the two leaves, link the new 1083 * Rebalance the entries across the two leaves, link the new
1084 * block into the leaves. 1084 * block into the leaves.
1085 */ 1085 */
1086 xfs_dir2_leafn_rebalance(state, oldblk, newblk); 1086 xfs_dir2_leafn_rebalance(state, oldblk, newblk);
1087 error = xfs_da_blk_link(state, oldblk, newblk); 1087 error = xfs_da_blk_link(state, oldblk, newblk);
1088 if (error) { 1088 if (error) {
1089 return error; 1089 return error;
1090 } 1090 }
1091 /* 1091 /*
1092 * Insert the new entry in the correct block. 1092 * Insert the new entry in the correct block.
1093 */ 1093 */
1094 if (state->inleaf) 1094 if (state->inleaf)
1095 error = xfs_dir2_leafn_add(oldblk->bp, args, oldblk->index); 1095 error = xfs_dir2_leafn_add(oldblk->bp, args, oldblk->index);
1096 else 1096 else
1097 error = xfs_dir2_leafn_add(newblk->bp, args, newblk->index); 1097 error = xfs_dir2_leafn_add(newblk->bp, args, newblk->index);
1098 /* 1098 /*
1099 * Update last hashval in each block since we added the name. 1099 * Update last hashval in each block since we added the name.
1100 */ 1100 */
1101 oldblk->hashval = xfs_dir2_leafn_lasthash(oldblk->bp, NULL); 1101 oldblk->hashval = xfs_dir2_leafn_lasthash(oldblk->bp, NULL);
1102 newblk->hashval = xfs_dir2_leafn_lasthash(newblk->bp, NULL); 1102 newblk->hashval = xfs_dir2_leafn_lasthash(newblk->bp, NULL);
1103 xfs_dir2_leafn_check(args->dp, oldblk->bp); 1103 xfs_dir2_leafn_check(args->dp, oldblk->bp);
1104 xfs_dir2_leafn_check(args->dp, newblk->bp); 1104 xfs_dir2_leafn_check(args->dp, newblk->bp);
1105 return error; 1105 return error;
1106 } 1106 }
1107 1107
1108 /* 1108 /*
1109 * Check a leaf block and its neighbors to see if the block should be 1109 * Check a leaf block and its neighbors to see if the block should be
1110 * collapsed into one or the other neighbor. Always keep the block 1110 * collapsed into one or the other neighbor. Always keep the block
1111 * with the smaller block number. 1111 * with the smaller block number.
1112 * If the current block is over 50% full, don't try to join it, return 0. 1112 * If the current block is over 50% full, don't try to join it, return 0.
1113 * If the block is empty, fill in the state structure and return 2. 1113 * If the block is empty, fill in the state structure and return 2.
1114 * If it can be collapsed, fill in the state structure and return 1. 1114 * If it can be collapsed, fill in the state structure and return 1.
1115 * If nothing can be done, return 0. 1115 * If nothing can be done, return 0.
1116 */ 1116 */
1117 int /* error */ 1117 int /* error */
1118 xfs_dir2_leafn_toosmall( 1118 xfs_dir2_leafn_toosmall(
1119 xfs_da_state_t *state, /* btree cursor */ 1119 xfs_da_state_t *state, /* btree cursor */
1120 int *action) /* resulting action to take */ 1120 int *action) /* resulting action to take */
1121 { 1121 {
1122 xfs_da_state_blk_t *blk; /* leaf block */ 1122 xfs_da_state_blk_t *blk; /* leaf block */
1123 xfs_dablk_t blkno; /* leaf block number */ 1123 xfs_dablk_t blkno; /* leaf block number */
1124 xfs_dabuf_t *bp; /* leaf buffer */ 1124 xfs_dabuf_t *bp; /* leaf buffer */
1125 int bytes; /* bytes in use */ 1125 int bytes; /* bytes in use */
1126 int count; /* leaf live entry count */ 1126 int count; /* leaf live entry count */
1127 int error; /* error return value */ 1127 int error; /* error return value */
1128 int forward; /* sibling block direction */ 1128 int forward; /* sibling block direction */
1129 int i; /* sibling counter */ 1129 int i; /* sibling counter */
1130 xfs_da_blkinfo_t *info; /* leaf block header */ 1130 xfs_da_blkinfo_t *info; /* leaf block header */
1131 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1131 xfs_dir2_leaf_t *leaf; /* leaf structure */
1132 int rval; /* result from path_shift */ 1132 int rval; /* result from path_shift */
1133 1133
1134 /* 1134 /*
1135 * Check for the degenerate case of the block being over 50% full. 1135 * Check for the degenerate case of the block being over 50% full.
1136 * If so, it's not worth even looking to see if we might be able 1136 * If so, it's not worth even looking to see if we might be able
1137 * to coalesce with a sibling. 1137 * to coalesce with a sibling.
1138 */ 1138 */
1139 blk = &state->path.blk[state->path.active - 1]; 1139 blk = &state->path.blk[state->path.active - 1];
1140 info = blk->bp->data; 1140 info = blk->bp->data;
1141 ASSERT(INT_GET(info->magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); 1141 ASSERT(INT_GET(info->magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
1142 leaf = (xfs_dir2_leaf_t *)info; 1142 leaf = (xfs_dir2_leaf_t *)info;
1143 count = INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT); 1143 count = INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT);
1144 bytes = (uint)sizeof(leaf->hdr) + count * (uint)sizeof(leaf->ents[0]); 1144 bytes = (uint)sizeof(leaf->hdr) + count * (uint)sizeof(leaf->ents[0]);
1145 if (bytes > (state->blocksize >> 1)) { 1145 if (bytes > (state->blocksize >> 1)) {
1146 /* 1146 /*
1147 * Blk over 50%, don't try to join. 1147 * Blk over 50%, don't try to join.
1148 */ 1148 */
1149 *action = 0; 1149 *action = 0;
1150 return 0; 1150 return 0;
1151 } 1151 }
1152 /* 1152 /*
1153 * Check for the degenerate case of the block being empty. 1153 * Check for the degenerate case of the block being empty.
1154 * If the block is empty, we'll simply delete it, no need to 1154 * If the block is empty, we'll simply delete it, no need to
1155 * coalesce it with a sibling block. We choose (arbitrarily) 1155 * coalesce it with a sibling block. We choose (arbitrarily)
1156 * to merge with the forward block unless it is NULL. 1156 * to merge with the forward block unless it is NULL.
1157 */ 1157 */
1158 if (count == 0) { 1158 if (count == 0) {
1159 /* 1159 /*
1160 * Make altpath point to the block we want to keep and 1160 * Make altpath point to the block we want to keep and
1161 * path point to the block we want to drop (this one). 1161 * path point to the block we want to drop (this one).
1162 */ 1162 */
1163 forward = info->forw; 1163 forward = info->forw;
1164 memcpy(&state->altpath, &state->path, sizeof(state->path)); 1164 memcpy(&state->altpath, &state->path, sizeof(state->path));
1165 error = xfs_da_path_shift(state, &state->altpath, forward, 0, 1165 error = xfs_da_path_shift(state, &state->altpath, forward, 0,
1166 &rval); 1166 &rval);
1167 if (error) 1167 if (error)
1168 return error; 1168 return error;
1169 *action = rval ? 2 : 0; 1169 *action = rval ? 2 : 0;
1170 return 0; 1170 return 0;
1171 } 1171 }
1172 /* 1172 /*
1173 * Examine each sibling block to see if we can coalesce with 1173 * Examine each sibling block to see if we can coalesce with
1174 * at least 25% free space to spare. We need to figure out 1174 * at least 25% free space to spare. We need to figure out
1175 * whether to merge with the forward or the backward block. 1175 * whether to merge with the forward or the backward block.
1176 * We prefer coalescing with the lower numbered sibling so as 1176 * We prefer coalescing with the lower numbered sibling so as
1177 * to shrink a directory over time. 1177 * to shrink a directory over time.
1178 */ 1178 */
1179 forward = INT_GET(info->forw, ARCH_CONVERT) < INT_GET(info->back, ARCH_CONVERT); 1179 forward = INT_GET(info->forw, ARCH_CONVERT) < INT_GET(info->back, ARCH_CONVERT);
1180 for (i = 0, bp = NULL; i < 2; forward = !forward, i++) { 1180 for (i = 0, bp = NULL; i < 2; forward = !forward, i++) {
1181 blkno = forward ?INT_GET( info->forw, ARCH_CONVERT) : INT_GET(info->back, ARCH_CONVERT); 1181 blkno = forward ?INT_GET( info->forw, ARCH_CONVERT) : INT_GET(info->back, ARCH_CONVERT);
1182 if (blkno == 0) 1182 if (blkno == 0)
1183 continue; 1183 continue;
1184 /* 1184 /*
1185 * Read the sibling leaf block. 1185 * Read the sibling leaf block.
1186 */ 1186 */
1187 if ((error = 1187 if ((error =
1188 xfs_da_read_buf(state->args->trans, state->args->dp, blkno, 1188 xfs_da_read_buf(state->args->trans, state->args->dp, blkno,
1189 -1, &bp, XFS_DATA_FORK))) { 1189 -1, &bp, XFS_DATA_FORK))) {
1190 return error; 1190 return error;
1191 } 1191 }
1192 ASSERT(bp != NULL); 1192 ASSERT(bp != NULL);
1193 /* 1193 /*
1194 * Count bytes in the two blocks combined. 1194 * Count bytes in the two blocks combined.
1195 */ 1195 */
1196 leaf = (xfs_dir2_leaf_t *)info; 1196 leaf = (xfs_dir2_leaf_t *)info;
1197 count = INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT); 1197 count = INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT);
1198 bytes = state->blocksize - (state->blocksize >> 2); 1198 bytes = state->blocksize - (state->blocksize >> 2);
1199 leaf = bp->data; 1199 leaf = bp->data;
1200 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); 1200 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
1201 count += INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT); 1201 count += INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT);
1202 bytes -= count * (uint)sizeof(leaf->ents[0]); 1202 bytes -= count * (uint)sizeof(leaf->ents[0]);
1203 /* 1203 /*
1204 * Fits with at least 25% to spare. 1204 * Fits with at least 25% to spare.
1205 */ 1205 */
1206 if (bytes >= 0) 1206 if (bytes >= 0)
1207 break; 1207 break;
1208 xfs_da_brelse(state->args->trans, bp); 1208 xfs_da_brelse(state->args->trans, bp);
1209 } 1209 }
1210 /* 1210 /*
1211 * Didn't like either block, give up. 1211 * Didn't like either block, give up.
1212 */ 1212 */
1213 if (i >= 2) { 1213 if (i >= 2) {
1214 *action = 0; 1214 *action = 0;
1215 return 0; 1215 return 0;
1216 } 1216 }
1217 /* 1217 /*
1218 * Done with the sibling leaf block here, drop the dabuf 1218 * Done with the sibling leaf block here, drop the dabuf
1219 * so path_shift can get it. 1219 * so path_shift can get it.
1220 */ 1220 */
1221 xfs_da_buf_done(bp); 1221 xfs_da_buf_done(bp);
1222 /* 1222 /*
1223 * Make altpath point to the block we want to keep (the lower 1223 * Make altpath point to the block we want to keep (the lower
1224 * numbered block) and path point to the block we want to drop. 1224 * numbered block) and path point to the block we want to drop.
1225 */ 1225 */
1226 memcpy(&state->altpath, &state->path, sizeof(state->path)); 1226 memcpy(&state->altpath, &state->path, sizeof(state->path));
1227 if (blkno < blk->blkno) 1227 if (blkno < blk->blkno)
1228 error = xfs_da_path_shift(state, &state->altpath, forward, 0, 1228 error = xfs_da_path_shift(state, &state->altpath, forward, 0,
1229 &rval); 1229 &rval);
1230 else 1230 else
1231 error = xfs_da_path_shift(state, &state->path, forward, 0, 1231 error = xfs_da_path_shift(state, &state->path, forward, 0,
1232 &rval); 1232 &rval);
1233 if (error) { 1233 if (error) {
1234 return error; 1234 return error;
1235 } 1235 }
1236 *action = rval ? 0 : 1; 1236 *action = rval ? 0 : 1;
1237 return 0; 1237 return 0;
1238 } 1238 }
1239 1239
1240 /* 1240 /*
1241 * Move all the leaf entries from drop_blk to save_blk. 1241 * Move all the leaf entries from drop_blk to save_blk.
1242 * This is done as part of a join operation. 1242 * This is done as part of a join operation.
1243 */ 1243 */
1244 void 1244 void
1245 xfs_dir2_leafn_unbalance( 1245 xfs_dir2_leafn_unbalance(
1246 xfs_da_state_t *state, /* cursor */ 1246 xfs_da_state_t *state, /* cursor */
1247 xfs_da_state_blk_t *drop_blk, /* dead block */ 1247 xfs_da_state_blk_t *drop_blk, /* dead block */
1248 xfs_da_state_blk_t *save_blk) /* surviving block */ 1248 xfs_da_state_blk_t *save_blk) /* surviving block */
1249 { 1249 {
1250 xfs_da_args_t *args; /* operation arguments */ 1250 xfs_da_args_t *args; /* operation arguments */
1251 xfs_dir2_leaf_t *drop_leaf; /* dead leaf structure */ 1251 xfs_dir2_leaf_t *drop_leaf; /* dead leaf structure */
1252 xfs_dir2_leaf_t *save_leaf; /* surviving leaf structure */ 1252 xfs_dir2_leaf_t *save_leaf; /* surviving leaf structure */
1253 1253
1254 args = state->args; 1254 args = state->args;
1255 ASSERT(drop_blk->magic == XFS_DIR2_LEAFN_MAGIC); 1255 ASSERT(drop_blk->magic == XFS_DIR2_LEAFN_MAGIC);
1256 ASSERT(save_blk->magic == XFS_DIR2_LEAFN_MAGIC); 1256 ASSERT(save_blk->magic == XFS_DIR2_LEAFN_MAGIC);
1257 drop_leaf = drop_blk->bp->data; 1257 drop_leaf = drop_blk->bp->data;
1258 save_leaf = save_blk->bp->data; 1258 save_leaf = save_blk->bp->data;
1259 ASSERT(INT_GET(drop_leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); 1259 ASSERT(INT_GET(drop_leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
1260 ASSERT(INT_GET(save_leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC); 1260 ASSERT(INT_GET(save_leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
1261 /* 1261 /*
1262 * If there are any stale leaf entries, take this opportunity 1262 * If there are any stale leaf entries, take this opportunity
1263 * to purge them. 1263 * to purge them.
1264 */ 1264 */
1265 if (INT_GET(drop_leaf->hdr.stale, ARCH_CONVERT)) 1265 if (INT_GET(drop_leaf->hdr.stale, ARCH_CONVERT))
1266 xfs_dir2_leaf_compact(args, drop_blk->bp); 1266 xfs_dir2_leaf_compact(args, drop_blk->bp);
1267 if (INT_GET(save_leaf->hdr.stale, ARCH_CONVERT)) 1267 if (INT_GET(save_leaf->hdr.stale, ARCH_CONVERT))
1268 xfs_dir2_leaf_compact(args, save_blk->bp); 1268 xfs_dir2_leaf_compact(args, save_blk->bp);
1269 /* 1269 /*
1270 * Move the entries from drop to the appropriate end of save. 1270 * Move the entries from drop to the appropriate end of save.
1271 */ 1271 */
1272 drop_blk->hashval = INT_GET(drop_leaf->ents[INT_GET(drop_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT); 1272 drop_blk->hashval = INT_GET(drop_leaf->ents[INT_GET(drop_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT);
1273 if (xfs_dir2_leafn_order(save_blk->bp, drop_blk->bp)) 1273 if (xfs_dir2_leafn_order(save_blk->bp, drop_blk->bp))
1274 xfs_dir2_leafn_moveents(args, drop_blk->bp, 0, save_blk->bp, 0, 1274 xfs_dir2_leafn_moveents(args, drop_blk->bp, 0, save_blk->bp, 0,
1275 INT_GET(drop_leaf->hdr.count, ARCH_CONVERT)); 1275 INT_GET(drop_leaf->hdr.count, ARCH_CONVERT));
1276 else 1276 else
1277 xfs_dir2_leafn_moveents(args, drop_blk->bp, 0, save_blk->bp, 1277 xfs_dir2_leafn_moveents(args, drop_blk->bp, 0, save_blk->bp,
1278 INT_GET(save_leaf->hdr.count, ARCH_CONVERT), INT_GET(drop_leaf->hdr.count, ARCH_CONVERT)); 1278 INT_GET(save_leaf->hdr.count, ARCH_CONVERT), INT_GET(drop_leaf->hdr.count, ARCH_CONVERT));
1279 save_blk->hashval = INT_GET(save_leaf->ents[INT_GET(save_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT); 1279 save_blk->hashval = INT_GET(save_leaf->ents[INT_GET(save_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT);
1280 xfs_dir2_leafn_check(args->dp, save_blk->bp); 1280 xfs_dir2_leafn_check(args->dp, save_blk->bp);
1281 } 1281 }
1282 1282
1283 /* 1283 /*
1284 * Top-level node form directory addname routine. 1284 * Top-level node form directory addname routine.
1285 */ 1285 */
1286 int /* error */ 1286 int /* error */
1287 xfs_dir2_node_addname( 1287 xfs_dir2_node_addname(
1288 xfs_da_args_t *args) /* operation arguments */ 1288 xfs_da_args_t *args) /* operation arguments */
1289 { 1289 {
1290 xfs_da_state_blk_t *blk; /* leaf block for insert */ 1290 xfs_da_state_blk_t *blk; /* leaf block for insert */
1291 int error; /* error return value */ 1291 int error; /* error return value */
1292 int rval; /* sub-return value */ 1292 int rval; /* sub-return value */
1293 xfs_da_state_t *state; /* btree cursor */ 1293 xfs_da_state_t *state; /* btree cursor */
1294 1294
1295 xfs_dir2_trace_args("node_addname", args); 1295 xfs_dir2_trace_args("node_addname", args);
1296 /* 1296 /*
1297 * Allocate and initialize the state (btree cursor). 1297 * Allocate and initialize the state (btree cursor).
1298 */ 1298 */
1299 state = xfs_da_state_alloc(); 1299 state = xfs_da_state_alloc();
1300 state->args = args; 1300 state->args = args;
1301 state->mp = args->dp->i_mount; 1301 state->mp = args->dp->i_mount;
1302 state->blocksize = state->mp->m_dirblksize; 1302 state->blocksize = state->mp->m_dirblksize;
1303 state->node_ents = state->mp->m_dir_node_ents; 1303 state->node_ents = state->mp->m_dir_node_ents;
1304 /* 1304 /*
1305 * Look up the name. We're not supposed to find it, but 1305 * Look up the name. We're not supposed to find it, but
1306 * this gives us the insertion point. 1306 * this gives us the insertion point.
1307 */ 1307 */
1308 error = xfs_da_node_lookup_int(state, &rval); 1308 error = xfs_da_node_lookup_int(state, &rval);
1309 if (error) 1309 if (error)
1310 rval = error; 1310 rval = error;
1311 if (rval != ENOENT) { 1311 if (rval != ENOENT) {
1312 goto done; 1312 goto done;
1313 } 1313 }
1314 /* 1314 /*
1315 * Add the data entry to a data block. 1315 * Add the data entry to a data block.
1316 * Extravalid is set to a freeblock found by lookup. 1316 * Extravalid is set to a freeblock found by lookup.
1317 */ 1317 */
1318 rval = xfs_dir2_node_addname_int(args, 1318 rval = xfs_dir2_node_addname_int(args,
1319 state->extravalid ? &state->extrablk : NULL); 1319 state->extravalid ? &state->extrablk : NULL);
1320 if (rval) { 1320 if (rval) {
1321 goto done; 1321 goto done;
1322 } 1322 }
1323 blk = &state->path.blk[state->path.active - 1]; 1323 blk = &state->path.blk[state->path.active - 1];
1324 ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC); 1324 ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC);
1325 /* 1325 /*
1326 * Add the new leaf entry. 1326 * Add the new leaf entry.
1327 */ 1327 */
1328 rval = xfs_dir2_leafn_add(blk->bp, args, blk->index); 1328 rval = xfs_dir2_leafn_add(blk->bp, args, blk->index);
1329 if (rval == 0) { 1329 if (rval == 0) {
1330 /* 1330 /*
1331 * It worked, fix the hash values up the btree. 1331 * It worked, fix the hash values up the btree.
1332 */ 1332 */
1333 if (!args->justcheck) 1333 if (!args->justcheck)
1334 xfs_da_fixhashpath(state, &state->path); 1334 xfs_da_fixhashpath(state, &state->path);
1335 } else { 1335 } else {
1336 /* 1336 /*
1337 * It didn't work, we need to split the leaf block. 1337 * It didn't work, we need to split the leaf block.
1338 */ 1338 */
1339 if (args->total == 0) { 1339 if (args->total == 0) {
1340 ASSERT(rval == ENOSPC); 1340 ASSERT(rval == ENOSPC);
1341 goto done; 1341 goto done;
1342 } 1342 }
1343 /* 1343 /*
1344 * Split the leaf block and insert the new entry. 1344 * Split the leaf block and insert the new entry.
1345 */ 1345 */
1346 rval = xfs_da_split(state); 1346 rval = xfs_da_split(state);
1347 } 1347 }
1348 done: 1348 done:
1349 xfs_da_state_free(state); 1349 xfs_da_state_free(state);
1350 return rval; 1350 return rval;
1351 } 1351 }
1352 1352
1353 /* 1353 /*
1354 * Add the data entry for a node-format directory name addition. 1354 * Add the data entry for a node-format directory name addition.
1355 * The leaf entry is added in xfs_dir2_leafn_add. 1355 * The leaf entry is added in xfs_dir2_leafn_add.
1356 * We may enter with a freespace block that the lookup found. 1356 * We may enter with a freespace block that the lookup found.
1357 */ 1357 */
1358 static int /* error */ 1358 static int /* error */
1359 xfs_dir2_node_addname_int( 1359 xfs_dir2_node_addname_int(
1360 xfs_da_args_t *args, /* operation arguments */ 1360 xfs_da_args_t *args, /* operation arguments */
1361 xfs_da_state_blk_t *fblk) /* optional freespace block */ 1361 xfs_da_state_blk_t *fblk) /* optional freespace block */
1362 { 1362 {
1363 xfs_dir2_data_t *data; /* data block structure */ 1363 xfs_dir2_data_t *data; /* data block structure */
1364 xfs_dir2_db_t dbno; /* data block number */ 1364 xfs_dir2_db_t dbno; /* data block number */
1365 xfs_dabuf_t *dbp; /* data block buffer */ 1365 xfs_dabuf_t *dbp; /* data block buffer */
1366 xfs_dir2_data_entry_t *dep; /* data entry pointer */ 1366 xfs_dir2_data_entry_t *dep; /* data entry pointer */
1367 xfs_inode_t *dp; /* incore directory inode */ 1367 xfs_inode_t *dp; /* incore directory inode */
1368 xfs_dir2_data_unused_t *dup; /* data unused entry pointer */ 1368 xfs_dir2_data_unused_t *dup; /* data unused entry pointer */
1369 int error; /* error return value */ 1369 int error; /* error return value */
1370 xfs_dir2_db_t fbno; /* freespace block number */ 1370 xfs_dir2_db_t fbno; /* freespace block number */
1371 xfs_dabuf_t *fbp; /* freespace buffer */ 1371 xfs_dabuf_t *fbp; /* freespace buffer */
1372 int findex; /* freespace entry index */ 1372 int findex; /* freespace entry index */
1373 xfs_dir2_free_t *free=NULL; /* freespace block structure */ 1373 xfs_dir2_free_t *free=NULL; /* freespace block structure */
1374 xfs_dir2_db_t ifbno; /* initial freespace block no */ 1374 xfs_dir2_db_t ifbno; /* initial freespace block no */
1375 xfs_dir2_db_t lastfbno=0; /* highest freespace block no */ 1375 xfs_dir2_db_t lastfbno=0; /* highest freespace block no */
1376 int length; /* length of the new entry */ 1376 int length; /* length of the new entry */
1377 int logfree; /* need to log free entry */ 1377 int logfree; /* need to log free entry */
1378 xfs_mount_t *mp; /* filesystem mount point */ 1378 xfs_mount_t *mp; /* filesystem mount point */
1379 int needlog; /* need to log data header */ 1379 int needlog; /* need to log data header */
1380 int needscan; /* need to rescan data frees */ 1380 int needscan; /* need to rescan data frees */
1381 xfs_dir2_data_off_t *tagp; /* data entry tag pointer */ 1381 xfs_dir2_data_off_t *tagp; /* data entry tag pointer */
1382 xfs_trans_t *tp; /* transaction pointer */ 1382 xfs_trans_t *tp; /* transaction pointer */
1383 1383
1384 dp = args->dp; 1384 dp = args->dp;
1385 mp = dp->i_mount; 1385 mp = dp->i_mount;
1386 tp = args->trans; 1386 tp = args->trans;
1387 length = XFS_DIR2_DATA_ENTSIZE(args->namelen); 1387 length = XFS_DIR2_DATA_ENTSIZE(args->namelen);
1388 /* 1388 /*
1389 * If we came in with a freespace block that means that lookup 1389 * If we came in with a freespace block that means that lookup
1390 * found an entry with our hash value. This is the freespace 1390 * found an entry with our hash value. This is the freespace
1391 * block for that data entry. 1391 * block for that data entry.
1392 */ 1392 */
1393 if (fblk) { 1393 if (fblk) {
1394 fbp = fblk->bp; 1394 fbp = fblk->bp;
1395 /* 1395 /*
1396 * Remember initial freespace block number. 1396 * Remember initial freespace block number.
1397 */ 1397 */
1398 ifbno = fblk->blkno; 1398 ifbno = fblk->blkno;
1399 free = fbp->data; 1399 free = fbp->data;
1400 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); 1400 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
1401 findex = fblk->index; 1401 findex = fblk->index;
1402 /* 1402 /*
1403 * This means the free entry showed that the data block had 1403 * This means the free entry showed that the data block had
1404 * space for our entry, so we remembered it. 1404 * space for our entry, so we remembered it.
1405 * Use that data block. 1405 * Use that data block.
1406 */ 1406 */
1407 if (findex >= 0) { 1407 if (findex >= 0) {
1408 ASSERT(findex < INT_GET(free->hdr.nvalid, ARCH_CONVERT)); 1408 ASSERT(findex < INT_GET(free->hdr.nvalid, ARCH_CONVERT));
1409 ASSERT(INT_GET(free->bests[findex], ARCH_CONVERT) != NULLDATAOFF); 1409 ASSERT(INT_GET(free->bests[findex], ARCH_CONVERT) != NULLDATAOFF);
1410 ASSERT(INT_GET(free->bests[findex], ARCH_CONVERT) >= length); 1410 ASSERT(INT_GET(free->bests[findex], ARCH_CONVERT) >= length);
1411 dbno = INT_GET(free->hdr.firstdb, ARCH_CONVERT) + findex; 1411 dbno = INT_GET(free->hdr.firstdb, ARCH_CONVERT) + findex;
1412 } 1412 }
1413 /* 1413 /*
1414 * The data block looked at didn't have enough room. 1414 * The data block looked at didn't have enough room.
1415 * We'll start at the beginning of the freespace entries. 1415 * We'll start at the beginning of the freespace entries.
1416 */ 1416 */
1417 else { 1417 else {
1418 dbno = -1; 1418 dbno = -1;
1419 findex = 0; 1419 findex = 0;
1420 } 1420 }
1421 } 1421 }
1422 /* 1422 /*
1423 * Didn't come in with a freespace block, so don't have a data block. 1423 * Didn't come in with a freespace block, so don't have a data block.
1424 */ 1424 */
1425 else { 1425 else {
1426 ifbno = dbno = -1; 1426 ifbno = dbno = -1;
1427 fbp = NULL; 1427 fbp = NULL;
1428 findex = 0; 1428 findex = 0;
1429 } 1429 }
1430 /* 1430 /*
1431 * If we don't have a data block yet, we're going to scan the 1431 * If we don't have a data block yet, we're going to scan the
1432 * freespace blocks looking for one. Figure out what the 1432 * freespace blocks looking for one. Figure out what the
1433 * highest freespace block number is. 1433 * highest freespace block number is.
1434 */ 1434 */
1435 if (dbno == -1) { 1435 if (dbno == -1) {
1436 xfs_fileoff_t fo; /* freespace block number */ 1436 xfs_fileoff_t fo; /* freespace block number */
1437 1437
1438 if ((error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK))) 1438 if ((error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK)))
1439 return error; 1439 return error;
1440 lastfbno = XFS_DIR2_DA_TO_DB(mp, (xfs_dablk_t)fo); 1440 lastfbno = XFS_DIR2_DA_TO_DB(mp, (xfs_dablk_t)fo);
1441 fbno = ifbno; 1441 fbno = ifbno;
1442 } 1442 }
1443 /* 1443 /*
1444 * While we haven't identified a data block, search the freeblock 1444 * While we haven't identified a data block, search the freeblock
1445 * data for a good data block. If we find a null freeblock entry, 1445 * data for a good data block. If we find a null freeblock entry,
1446 * indicating a hole in the data blocks, remember that. 1446 * indicating a hole in the data blocks, remember that.
1447 */ 1447 */
1448 while (dbno == -1) { 1448 while (dbno == -1) {
1449 /* 1449 /*
1450 * If we don't have a freeblock in hand, get the next one. 1450 * If we don't have a freeblock in hand, get the next one.
1451 */ 1451 */
1452 if (fbp == NULL) { 1452 if (fbp == NULL) {
1453 /* 1453 /*
1454 * Happens the first time through unless lookup gave 1454 * Happens the first time through unless lookup gave
1455 * us a freespace block to start with. 1455 * us a freespace block to start with.
1456 */ 1456 */
1457 if (++fbno == 0) 1457 if (++fbno == 0)
1458 fbno = XFS_DIR2_FREE_FIRSTDB(mp); 1458 fbno = XFS_DIR2_FREE_FIRSTDB(mp);
1459 /* 1459 /*
1460 * If it's ifbno we already looked at it. 1460 * If it's ifbno we already looked at it.
1461 */ 1461 */
1462 if (fbno == ifbno) 1462 if (fbno == ifbno)
1463 fbno++; 1463 fbno++;
1464 /* 1464 /*
1465 * If it's off the end we're done. 1465 * If it's off the end we're done.
1466 */ 1466 */
1467 if (fbno >= lastfbno) 1467 if (fbno >= lastfbno)
1468 break; 1468 break;
1469 /* 1469 /*
1470 * Read the block. There can be holes in the 1470 * Read the block. There can be holes in the
1471 * freespace blocks, so this might not succeed. 1471 * freespace blocks, so this might not succeed.
1472 * This should be really rare, so there's no reason 1472 * This should be really rare, so there's no reason
1473 * to avoid it. 1473 * to avoid it.
1474 */ 1474 */
1475 if ((error = xfs_da_read_buf(tp, dp, 1475 if ((error = xfs_da_read_buf(tp, dp,
1476 XFS_DIR2_DB_TO_DA(mp, fbno), -2, &fbp, 1476 XFS_DIR2_DB_TO_DA(mp, fbno), -2, &fbp,
1477 XFS_DATA_FORK))) { 1477 XFS_DATA_FORK))) {
1478 return error; 1478 return error;
1479 } 1479 }
1480 if (unlikely(fbp == NULL)) { 1480 if (unlikely(fbp == NULL)) {
1481 continue; 1481 continue;
1482 } 1482 }
1483 free = fbp->data; 1483 free = fbp->data;
1484 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); 1484 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
1485 findex = 0; 1485 findex = 0;
1486 } 1486 }
1487 /* 1487 /*
1488 * Look at the current free entry. Is it good enough? 1488 * Look at the current free entry. Is it good enough?
1489 */ 1489 */
1490 if (INT_GET(free->bests[findex], ARCH_CONVERT) != NULLDATAOFF && 1490 if (INT_GET(free->bests[findex], ARCH_CONVERT) != NULLDATAOFF &&
1491 INT_GET(free->bests[findex], ARCH_CONVERT) >= length) 1491 INT_GET(free->bests[findex], ARCH_CONVERT) >= length)
1492 dbno = INT_GET(free->hdr.firstdb, ARCH_CONVERT) + findex; 1492 dbno = INT_GET(free->hdr.firstdb, ARCH_CONVERT) + findex;
1493 else { 1493 else {
1494 /* 1494 /*
1495 * Are we done with the freeblock? 1495 * Are we done with the freeblock?
1496 */ 1496 */
1497 if (++findex == INT_GET(free->hdr.nvalid, ARCH_CONVERT)) { 1497 if (++findex == INT_GET(free->hdr.nvalid, ARCH_CONVERT)) {
1498 /* 1498 /*
1499 * Drop the block. 1499 * Drop the block.
1500 */ 1500 */
1501 xfs_da_brelse(tp, fbp); 1501 xfs_da_brelse(tp, fbp);
1502 fbp = NULL; 1502 fbp = NULL;
1503 if (fblk && fblk->bp) 1503 if (fblk && fblk->bp)
1504 fblk->bp = NULL; 1504 fblk->bp = NULL;
1505 } 1505 }
1506 } 1506 }
1507 } 1507 }
1508 /* 1508 /*
1509 * If we don't have a data block, we need to allocate one and make 1509 * If we don't have a data block, we need to allocate one and make
1510 * the freespace entries refer to it. 1510 * the freespace entries refer to it.
1511 */ 1511 */
1512 if (unlikely(dbno == -1)) { 1512 if (unlikely(dbno == -1)) {
1513 /* 1513 /*
1514 * Not allowed to allocate, return failure. 1514 * Not allowed to allocate, return failure.
1515 */ 1515 */
1516 if (args->justcheck || args->total == 0) { 1516 if (args->justcheck || args->total == 0) {
1517 /* 1517 /*
1518 * Drop the freespace buffer unless it came from our 1518 * Drop the freespace buffer unless it came from our
1519 * caller. 1519 * caller.
1520 */ 1520 */
1521 if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) 1521 if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL)
1522 xfs_da_buf_done(fbp); 1522 xfs_da_buf_done(fbp);
1523 return XFS_ERROR(ENOSPC); 1523 return XFS_ERROR(ENOSPC);
1524 } 1524 }
1525 /* 1525 /*
1526 * Allocate and initialize the new data block. 1526 * Allocate and initialize the new data block.
1527 */ 1527 */
1528 if (unlikely((error = xfs_dir2_grow_inode(args, 1528 if (unlikely((error = xfs_dir2_grow_inode(args,
1529 XFS_DIR2_DATA_SPACE, 1529 XFS_DIR2_DATA_SPACE,
1530 &dbno)) || 1530 &dbno)) ||
1531 (error = xfs_dir2_data_init(args, dbno, &dbp)))) { 1531 (error = xfs_dir2_data_init(args, dbno, &dbp)))) {
1532 /* 1532 /*
1533 * Drop the freespace buffer unless it came from our 1533 * Drop the freespace buffer unless it came from our
1534 * caller. 1534 * caller.
1535 */ 1535 */
1536 if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) 1536 if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL)
1537 xfs_da_buf_done(fbp); 1537 xfs_da_buf_done(fbp);
1538 return error; 1538 return error;
1539 } 1539 }
1540 /* 1540 /*
1541 * If (somehow) we have a freespace block, get rid of it. 1541 * If (somehow) we have a freespace block, get rid of it.
1542 */ 1542 */
1543 if (fbp) 1543 if (fbp)
1544 xfs_da_brelse(tp, fbp); 1544 xfs_da_brelse(tp, fbp);
1545 if (fblk && fblk->bp) 1545 if (fblk && fblk->bp)
1546 fblk->bp = NULL; 1546 fblk->bp = NULL;
1547 1547
1548 /* 1548 /*
1549 * Get the freespace block corresponding to the data block 1549 * Get the freespace block corresponding to the data block
1550 * that was just allocated. 1550 * that was just allocated.
1551 */ 1551 */
1552 fbno = XFS_DIR2_DB_TO_FDB(mp, dbno); 1552 fbno = XFS_DIR2_DB_TO_FDB(mp, dbno);
1553 if (unlikely(error = xfs_da_read_buf(tp, dp, 1553 if (unlikely(error = xfs_da_read_buf(tp, dp,
1554 XFS_DIR2_DB_TO_DA(mp, fbno), -2, &fbp, 1554 XFS_DIR2_DB_TO_DA(mp, fbno), -2, &fbp,
1555 XFS_DATA_FORK))) { 1555 XFS_DATA_FORK))) {
1556 xfs_da_buf_done(dbp); 1556 xfs_da_buf_done(dbp);
1557 return error; 1557 return error;
1558 } 1558 }
1559 /* 1559 /*
1560 * If there wasn't a freespace block, the read will 1560 * If there wasn't a freespace block, the read will
1561 * return a NULL fbp. Allocate and initialize a new one. 1561 * return a NULL fbp. Allocate and initialize a new one.
1562 */ 1562 */
1563 if( fbp == NULL ) { 1563 if( fbp == NULL ) {
1564 if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, 1564 if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE,
1565 &fbno))) { 1565 &fbno))) {
1566 return error; 1566 return error;
1567 } 1567 }
1568 1568
1569 if (unlikely(XFS_DIR2_DB_TO_FDB(mp, dbno) != fbno)) { 1569 if (unlikely(XFS_DIR2_DB_TO_FDB(mp, dbno) != fbno)) {
1570 cmn_err(CE_ALERT, 1570 cmn_err(CE_ALERT,
1571 "xfs_dir2_node_addname_int: dir ino " 1571 "xfs_dir2_node_addname_int: dir ino "
1572 "%llu needed freesp block %lld for\n" 1572 "%llu needed freesp block %lld for\n"
1573 " data block %lld, got %lld\n" 1573 " data block %lld, got %lld\n"
1574 " ifbno %llu lastfbno %d\n", 1574 " ifbno %llu lastfbno %d\n",
1575 (unsigned long long)dp->i_ino, 1575 (unsigned long long)dp->i_ino,
1576 (long long)XFS_DIR2_DB_TO_FDB(mp, dbno), 1576 (long long)XFS_DIR2_DB_TO_FDB(mp, dbno),
1577 (long long)dbno, (long long)fbno, 1577 (long long)dbno, (long long)fbno,
1578 (unsigned long long)ifbno, lastfbno); 1578 (unsigned long long)ifbno, lastfbno);
1579 if (fblk) { 1579 if (fblk) {
1580 cmn_err(CE_ALERT, 1580 cmn_err(CE_ALERT,
1581 " fblk 0x%p blkno %llu " 1581 " fblk 0x%p blkno %llu "
1582 "index %d magic 0x%x\n", 1582 "index %d magic 0x%x\n",
1583 fblk, 1583 fblk,
1584 (unsigned long long)fblk->blkno, 1584 (unsigned long long)fblk->blkno,
1585 fblk->index, 1585 fblk->index,
1586 fblk->magic); 1586 fblk->magic);
1587 } else { 1587 } else {
1588 cmn_err(CE_ALERT, 1588 cmn_err(CE_ALERT,
1589 " ... fblk is NULL\n"); 1589 " ... fblk is NULL\n");
1590 } 1590 }
1591 XFS_ERROR_REPORT("xfs_dir2_node_addname_int", 1591 XFS_ERROR_REPORT("xfs_dir2_node_addname_int",
1592 XFS_ERRLEVEL_LOW, mp); 1592 XFS_ERRLEVEL_LOW, mp);
1593 return XFS_ERROR(EFSCORRUPTED); 1593 return XFS_ERROR(EFSCORRUPTED);
1594 } 1594 }
1595 1595
1596 /* 1596 /*
1597 * Get a buffer for the new block. 1597 * Get a buffer for the new block.
1598 */ 1598 */
1599 if ((error = xfs_da_get_buf(tp, dp, 1599 if ((error = xfs_da_get_buf(tp, dp,
1600 XFS_DIR2_DB_TO_DA(mp, fbno), 1600 XFS_DIR2_DB_TO_DA(mp, fbno),
1601 -1, &fbp, XFS_DATA_FORK))) { 1601 -1, &fbp, XFS_DATA_FORK))) {
1602 return error; 1602 return error;
1603 } 1603 }
1604 ASSERT(fbp != NULL); 1604 ASSERT(fbp != NULL);
1605 1605
1606 /* 1606 /*
1607 * Initialize the new block to be empty, and remember 1607 * Initialize the new block to be empty, and remember
1608 * its first slot as our empty slot. 1608 * its first slot as our empty slot.
1609 */ 1609 */
1610 free = fbp->data; 1610 free = fbp->data;
1611 INT_SET(free->hdr.magic, ARCH_CONVERT, XFS_DIR2_FREE_MAGIC); 1611 INT_SET(free->hdr.magic, ARCH_CONVERT, XFS_DIR2_FREE_MAGIC);
1612 INT_SET(free->hdr.firstdb, ARCH_CONVERT, 1612 INT_SET(free->hdr.firstdb, ARCH_CONVERT,
1613 (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) * 1613 (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) *
1614 XFS_DIR2_MAX_FREE_BESTS(mp)); 1614 XFS_DIR2_MAX_FREE_BESTS(mp));
1615 free->hdr.nvalid = 0; 1615 free->hdr.nvalid = 0;
1616 free->hdr.nused = 0; 1616 free->hdr.nused = 0;
1617 } else { 1617 } else {
1618 free = fbp->data; 1618 free = fbp->data;
1619 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); 1619 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
1620 } 1620 }
1621 1621
1622 /* 1622 /*
1623 * Set the freespace block index from the data block number. 1623 * Set the freespace block index from the data block number.
1624 */ 1624 */
1625 findex = XFS_DIR2_DB_TO_FDINDEX(mp, dbno); 1625 findex = XFS_DIR2_DB_TO_FDINDEX(mp, dbno);
1626 /* 1626 /*
1627 * If it's after the end of the current entries in the 1627 * If it's after the end of the current entries in the
1628 * freespace block, extend that table. 1628 * freespace block, extend that table.
1629 */ 1629 */
1630 if (findex >= INT_GET(free->hdr.nvalid, ARCH_CONVERT)) { 1630 if (findex >= INT_GET(free->hdr.nvalid, ARCH_CONVERT)) {
1631 ASSERT(findex < XFS_DIR2_MAX_FREE_BESTS(mp)); 1631 ASSERT(findex < XFS_DIR2_MAX_FREE_BESTS(mp));
1632 INT_SET(free->hdr.nvalid, ARCH_CONVERT, findex + 1); 1632 INT_SET(free->hdr.nvalid, ARCH_CONVERT, findex + 1);
1633 /* 1633 /*
1634 * Tag new entry so nused will go up. 1634 * Tag new entry so nused will go up.
1635 */ 1635 */
1636 INT_SET(free->bests[findex], ARCH_CONVERT, NULLDATAOFF); 1636 INT_SET(free->bests[findex], ARCH_CONVERT, NULLDATAOFF);
1637 } 1637 }
1638 /* 1638 /*
1639 * If this entry was for an empty data block 1639 * If this entry was for an empty data block
1640 * (this should always be true) then update the header. 1640 * (this should always be true) then update the header.
1641 */ 1641 */
1642 if (INT_GET(free->bests[findex], ARCH_CONVERT) == NULLDATAOFF) { 1642 if (INT_GET(free->bests[findex], ARCH_CONVERT) == NULLDATAOFF) {
1643 INT_MOD(free->hdr.nused, ARCH_CONVERT, +1); 1643 INT_MOD(free->hdr.nused, ARCH_CONVERT, +1);
1644 xfs_dir2_free_log_header(tp, fbp); 1644 xfs_dir2_free_log_header(tp, fbp);
1645 } 1645 }
1646 /* 1646 /*
1647 * Update the real value in the table. 1647 * Update the real value in the table.
1648 * We haven't allocated the data entry yet so this will 1648 * We haven't allocated the data entry yet so this will
1649 * change again. 1649 * change again.
1650 */ 1650 */
1651 data = dbp->data; 1651 data = dbp->data;
1652 INT_COPY(free->bests[findex], data->hdr.bestfree[0].length, ARCH_CONVERT); 1652 free->bests[findex] = data->hdr.bestfree[0].length;
1653 logfree = 1; 1653 logfree = 1;
1654 } 1654 }
1655 /* 1655 /*
1656 * We had a data block so we don't have to make a new one. 1656 * We had a data block so we don't have to make a new one.
1657 */ 1657 */
1658 else { 1658 else {
1659 /* 1659 /*
1660 * If just checking, we succeeded. 1660 * If just checking, we succeeded.
1661 */ 1661 */
1662 if (args->justcheck) { 1662 if (args->justcheck) {
1663 if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) 1663 if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL)
1664 xfs_da_buf_done(fbp); 1664 xfs_da_buf_done(fbp);
1665 return 0; 1665 return 0;
1666 } 1666 }
1667 /* 1667 /*
1668 * Read the data block in. 1668 * Read the data block in.
1669 */ 1669 */
1670 if (unlikely( 1670 if (unlikely(
1671 error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, dbno), 1671 error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, dbno),
1672 -1, &dbp, XFS_DATA_FORK))) { 1672 -1, &dbp, XFS_DATA_FORK))) {
1673 if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) 1673 if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL)
1674 xfs_da_buf_done(fbp); 1674 xfs_da_buf_done(fbp);
1675 return error; 1675 return error;
1676 } 1676 }
1677 data = dbp->data; 1677 data = dbp->data;
1678 logfree = 0; 1678 logfree = 0;
1679 } 1679 }
1680 ASSERT(INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT) >= length); 1680 ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) >= length);
1681 /* 1681 /*
1682 * Point to the existing unused space. 1682 * Point to the existing unused space.
1683 */ 1683 */
1684 dup = (xfs_dir2_data_unused_t *) 1684 dup = (xfs_dir2_data_unused_t *)
1685 ((char *)data + INT_GET(data->hdr.bestfree[0].offset, ARCH_CONVERT)); 1685 ((char *)data + be16_to_cpu(data->hdr.bestfree[0].offset));
1686 needscan = needlog = 0; 1686 needscan = needlog = 0;
1687 /* 1687 /*
1688 * Mark the first part of the unused space, inuse for us. 1688 * Mark the first part of the unused space, inuse for us.
1689 */ 1689 */
1690 xfs_dir2_data_use_free(tp, dbp, dup, 1690 xfs_dir2_data_use_free(tp, dbp, dup,
1691 (xfs_dir2_data_aoff_t)((char *)dup - (char *)data), length, 1691 (xfs_dir2_data_aoff_t)((char *)dup - (char *)data), length,
1692 &needlog, &needscan); 1692 &needlog, &needscan);
1693 /* 1693 /*
1694 * Fill in the new entry and log it. 1694 * Fill in the new entry and log it.
1695 */ 1695 */
1696 dep = (xfs_dir2_data_entry_t *)dup; 1696 dep = (xfs_dir2_data_entry_t *)dup;
1697 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 1697 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
1698 dep->namelen = args->namelen; 1698 dep->namelen = args->namelen;
1699 memcpy(dep->name, args->name, dep->namelen); 1699 memcpy(dep->name, args->name, dep->namelen);
1700 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 1700 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
1701 INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)data)); 1701 INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)data));
1702 xfs_dir2_data_log_entry(tp, dbp, dep); 1702 xfs_dir2_data_log_entry(tp, dbp, dep);
1703 /* 1703 /*
1704 * Rescan the block for bestfree if needed. 1704 * Rescan the block for bestfree if needed.
1705 */ 1705 */
1706 if (needscan) 1706 if (needscan)
1707 xfs_dir2_data_freescan(mp, data, &needlog, NULL); 1707 xfs_dir2_data_freescan(mp, data, &needlog, NULL);
1708 /* 1708 /*
1709 * Log the data block header if needed. 1709 * Log the data block header if needed.
1710 */ 1710 */
1711 if (needlog) 1711 if (needlog)
1712 xfs_dir2_data_log_header(tp, dbp); 1712 xfs_dir2_data_log_header(tp, dbp);
1713 /* 1713 /*
1714 * If the freespace entry is now wrong, update it. 1714 * If the freespace entry is now wrong, update it.
1715 */ 1715 */
1716 if (INT_GET(free->bests[findex], ARCH_CONVERT) != INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT)) { 1716 if (INT_GET(free->bests[findex], ARCH_CONVERT) != be16_to_cpu(data->hdr.bestfree[0].length)) {
1717 INT_COPY(free->bests[findex], data->hdr.bestfree[0].length, ARCH_CONVERT); 1717 free->bests[findex] = data->hdr.bestfree[0].length;
1718 logfree = 1; 1718 logfree = 1;
1719 } 1719 }
1720 /* 1720 /*
1721 * Log the freespace entry if needed. 1721 * Log the freespace entry if needed.
1722 */ 1722 */
1723 if (logfree) 1723 if (logfree)
1724 xfs_dir2_free_log_bests(tp, fbp, findex, findex); 1724 xfs_dir2_free_log_bests(tp, fbp, findex, findex);
1725 /* 1725 /*
1726 * If the caller didn't hand us the freespace block, drop it. 1726 * If the caller didn't hand us the freespace block, drop it.
1727 */ 1727 */
1728 if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) 1728 if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL)
1729 xfs_da_buf_done(fbp); 1729 xfs_da_buf_done(fbp);
1730 /* 1730 /*
1731 * Return the data block and offset in args, then drop the data block. 1731 * Return the data block and offset in args, then drop the data block.
1732 */ 1732 */
1733 args->blkno = (xfs_dablk_t)dbno; 1733 args->blkno = (xfs_dablk_t)dbno;
1734 args->index = INT_GET(*tagp, ARCH_CONVERT); 1734 args->index = INT_GET(*tagp, ARCH_CONVERT);
1735 xfs_da_buf_done(dbp); 1735 xfs_da_buf_done(dbp);
1736 return 0; 1736 return 0;
1737 } 1737 }
1738 1738
1739 /* 1739 /*
1740 * Lookup an entry in a node-format directory. 1740 * Lookup an entry in a node-format directory.
1741 * All the real work happens in xfs_da_node_lookup_int. 1741 * All the real work happens in xfs_da_node_lookup_int.
1742 * The only real output is the inode number of the entry. 1742 * The only real output is the inode number of the entry.
1743 */ 1743 */
1744 int /* error */ 1744 int /* error */
1745 xfs_dir2_node_lookup( 1745 xfs_dir2_node_lookup(
1746 xfs_da_args_t *args) /* operation arguments */ 1746 xfs_da_args_t *args) /* operation arguments */
1747 { 1747 {
1748 int error; /* error return value */ 1748 int error; /* error return value */
1749 int i; /* btree level */ 1749 int i; /* btree level */
1750 int rval; /* operation return value */ 1750 int rval; /* operation return value */
1751 xfs_da_state_t *state; /* btree cursor */ 1751 xfs_da_state_t *state; /* btree cursor */
1752 1752
1753 xfs_dir2_trace_args("node_lookup", args); 1753 xfs_dir2_trace_args("node_lookup", args);
1754 /* 1754 /*
1755 * Allocate and initialize the btree cursor. 1755 * Allocate and initialize the btree cursor.
1756 */ 1756 */
1757 state = xfs_da_state_alloc(); 1757 state = xfs_da_state_alloc();
1758 state->args = args; 1758 state->args = args;
1759 state->mp = args->dp->i_mount; 1759 state->mp = args->dp->i_mount;
1760 state->blocksize = state->mp->m_dirblksize; 1760 state->blocksize = state->mp->m_dirblksize;
1761 state->node_ents = state->mp->m_dir_node_ents; 1761 state->node_ents = state->mp->m_dir_node_ents;
1762 /* 1762 /*
1763 * Fill in the path to the entry in the cursor. 1763 * Fill in the path to the entry in the cursor.
1764 */ 1764 */
1765 error = xfs_da_node_lookup_int(state, &rval); 1765 error = xfs_da_node_lookup_int(state, &rval);
1766 if (error) 1766 if (error)
1767 rval = error; 1767 rval = error;
1768 /* 1768 /*
1769 * Release the btree blocks and leaf block. 1769 * Release the btree blocks and leaf block.
1770 */ 1770 */
1771 for (i = 0; i < state->path.active; i++) { 1771 for (i = 0; i < state->path.active; i++) {
1772 xfs_da_brelse(args->trans, state->path.blk[i].bp); 1772 xfs_da_brelse(args->trans, state->path.blk[i].bp);
1773 state->path.blk[i].bp = NULL; 1773 state->path.blk[i].bp = NULL;
1774 } 1774 }
1775 /* 1775 /*
1776 * Release the data block if we have it. 1776 * Release the data block if we have it.
1777 */ 1777 */
1778 if (state->extravalid && state->extrablk.bp) { 1778 if (state->extravalid && state->extrablk.bp) {
1779 xfs_da_brelse(args->trans, state->extrablk.bp); 1779 xfs_da_brelse(args->trans, state->extrablk.bp);
1780 state->extrablk.bp = NULL; 1780 state->extrablk.bp = NULL;
1781 } 1781 }
1782 xfs_da_state_free(state); 1782 xfs_da_state_free(state);
1783 return rval; 1783 return rval;
1784 } 1784 }
1785 1785
1786 /* 1786 /*
1787 * Remove an entry from a node-format directory. 1787 * Remove an entry from a node-format directory.
1788 */ 1788 */
1789 int /* error */ 1789 int /* error */
1790 xfs_dir2_node_removename( 1790 xfs_dir2_node_removename(
1791 xfs_da_args_t *args) /* operation arguments */ 1791 xfs_da_args_t *args) /* operation arguments */
1792 { 1792 {
1793 xfs_da_state_blk_t *blk; /* leaf block */ 1793 xfs_da_state_blk_t *blk; /* leaf block */
1794 int error; /* error return value */ 1794 int error; /* error return value */
1795 int rval; /* operation return value */ 1795 int rval; /* operation return value */
1796 xfs_da_state_t *state; /* btree cursor */ 1796 xfs_da_state_t *state; /* btree cursor */
1797 1797
1798 xfs_dir2_trace_args("node_removename", args); 1798 xfs_dir2_trace_args("node_removename", args);
1799 /* 1799 /*
1800 * Allocate and initialize the btree cursor. 1800 * Allocate and initialize the btree cursor.
1801 */ 1801 */
1802 state = xfs_da_state_alloc(); 1802 state = xfs_da_state_alloc();
1803 state->args = args; 1803 state->args = args;
1804 state->mp = args->dp->i_mount; 1804 state->mp = args->dp->i_mount;
1805 state->blocksize = state->mp->m_dirblksize; 1805 state->blocksize = state->mp->m_dirblksize;
1806 state->node_ents = state->mp->m_dir_node_ents; 1806 state->node_ents = state->mp->m_dir_node_ents;
1807 /* 1807 /*
1808 * Look up the entry we're deleting, set up the cursor. 1808 * Look up the entry we're deleting, set up the cursor.
1809 */ 1809 */
1810 error = xfs_da_node_lookup_int(state, &rval); 1810 error = xfs_da_node_lookup_int(state, &rval);
1811 if (error) { 1811 if (error) {
1812 rval = error; 1812 rval = error;
1813 } 1813 }
1814 /* 1814 /*
1815 * Didn't find it, upper layer screwed up. 1815 * Didn't find it, upper layer screwed up.
1816 */ 1816 */
1817 if (rval != EEXIST) { 1817 if (rval != EEXIST) {
1818 xfs_da_state_free(state); 1818 xfs_da_state_free(state);
1819 return rval; 1819 return rval;
1820 } 1820 }
1821 blk = &state->path.blk[state->path.active - 1]; 1821 blk = &state->path.blk[state->path.active - 1];
1822 ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC); 1822 ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC);
1823 ASSERT(state->extravalid); 1823 ASSERT(state->extravalid);
1824 /* 1824 /*
1825 * Remove the leaf and data entries. 1825 * Remove the leaf and data entries.
1826 * Extrablk refers to the data block. 1826 * Extrablk refers to the data block.
1827 */ 1827 */
1828 error = xfs_dir2_leafn_remove(args, blk->bp, blk->index, 1828 error = xfs_dir2_leafn_remove(args, blk->bp, blk->index,
1829 &state->extrablk, &rval); 1829 &state->extrablk, &rval);
1830 if (error) { 1830 if (error) {
1831 return error; 1831 return error;
1832 } 1832 }
1833 /* 1833 /*
1834 * Fix the hash values up the btree. 1834 * Fix the hash values up the btree.
1835 */ 1835 */
1836 xfs_da_fixhashpath(state, &state->path); 1836 xfs_da_fixhashpath(state, &state->path);
1837 /* 1837 /*
1838 * If we need to join leaf blocks, do it. 1838 * If we need to join leaf blocks, do it.
1839 */ 1839 */
1840 if (rval && state->path.active > 1) 1840 if (rval && state->path.active > 1)
1841 error = xfs_da_join(state); 1841 error = xfs_da_join(state);
1842 /* 1842 /*
1843 * If no errors so far, try conversion to leaf format. 1843 * If no errors so far, try conversion to leaf format.
1844 */ 1844 */
1845 if (!error) 1845 if (!error)
1846 error = xfs_dir2_node_to_leaf(state); 1846 error = xfs_dir2_node_to_leaf(state);
1847 xfs_da_state_free(state); 1847 xfs_da_state_free(state);
1848 return error; 1848 return error;
1849 } 1849 }
1850 1850
1851 /* 1851 /*
1852 * Replace an entry's inode number in a node-format directory. 1852 * Replace an entry's inode number in a node-format directory.
1853 */ 1853 */
1854 int /* error */ 1854 int /* error */
1855 xfs_dir2_node_replace( 1855 xfs_dir2_node_replace(
1856 xfs_da_args_t *args) /* operation arguments */ 1856 xfs_da_args_t *args) /* operation arguments */
1857 { 1857 {
1858 xfs_da_state_blk_t *blk; /* leaf block */ 1858 xfs_da_state_blk_t *blk; /* leaf block */
1859 xfs_dir2_data_t *data; /* data block structure */ 1859 xfs_dir2_data_t *data; /* data block structure */
1860 xfs_dir2_data_entry_t *dep; /* data entry changed */ 1860 xfs_dir2_data_entry_t *dep; /* data entry changed */
1861 int error; /* error return value */ 1861 int error; /* error return value */
1862 int i; /* btree level */ 1862 int i; /* btree level */
1863 xfs_ino_t inum; /* new inode number */ 1863 xfs_ino_t inum; /* new inode number */
1864 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1864 xfs_dir2_leaf_t *leaf; /* leaf structure */
1865 xfs_dir2_leaf_entry_t *lep; /* leaf entry being changed */ 1865 xfs_dir2_leaf_entry_t *lep; /* leaf entry being changed */
1866 int rval; /* internal return value */ 1866 int rval; /* internal return value */
1867 xfs_da_state_t *state; /* btree cursor */ 1867 xfs_da_state_t *state; /* btree cursor */
1868 1868
1869 xfs_dir2_trace_args("node_replace", args); 1869 xfs_dir2_trace_args("node_replace", args);
1870 /* 1870 /*
1871 * Allocate and initialize the btree cursor. 1871 * Allocate and initialize the btree cursor.
1872 */ 1872 */
1873 state = xfs_da_state_alloc(); 1873 state = xfs_da_state_alloc();
1874 state->args = args; 1874 state->args = args;
1875 state->mp = args->dp->i_mount; 1875 state->mp = args->dp->i_mount;
1876 state->blocksize = state->mp->m_dirblksize; 1876 state->blocksize = state->mp->m_dirblksize;
1877 state->node_ents = state->mp->m_dir_node_ents; 1877 state->node_ents = state->mp->m_dir_node_ents;
1878 inum = args->inumber; 1878 inum = args->inumber;
1879 /* 1879 /*
1880 * Lookup the entry to change in the btree. 1880 * Lookup the entry to change in the btree.
1881 */ 1881 */
1882 error = xfs_da_node_lookup_int(state, &rval); 1882 error = xfs_da_node_lookup_int(state, &rval);
1883 if (error) { 1883 if (error) {
1884 rval = error; 1884 rval = error;
1885 } 1885 }
1886 /* 1886 /*
1887 * It should be found, since the vnodeops layer has looked it up 1887 * It should be found, since the vnodeops layer has looked it up
1888 * and locked it. But paranoia is good. 1888 * and locked it. But paranoia is good.
1889 */ 1889 */
1890 if (rval == EEXIST) { 1890 if (rval == EEXIST) {
1891 /* 1891 /*
1892 * Find the leaf entry. 1892 * Find the leaf entry.
1893 */ 1893 */
1894 blk = &state->path.blk[state->path.active - 1]; 1894 blk = &state->path.blk[state->path.active - 1];
1895 ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC); 1895 ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC);
1896 leaf = blk->bp->data; 1896 leaf = blk->bp->data;
1897 lep = &leaf->ents[blk->index]; 1897 lep = &leaf->ents[blk->index];
1898 ASSERT(state->extravalid); 1898 ASSERT(state->extravalid);
1899 /* 1899 /*
1900 * Point to the data entry. 1900 * Point to the data entry.
1901 */ 1901 */
1902 data = state->extrablk.bp->data; 1902 data = state->extrablk.bp->data;
1903 ASSERT(INT_GET(data->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC); 1903 ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC);
1904 dep = (xfs_dir2_data_entry_t *) 1904 dep = (xfs_dir2_data_entry_t *)
1905 ((char *)data + 1905 ((char *)data +
1906 XFS_DIR2_DATAPTR_TO_OFF(state->mp, INT_GET(lep->address, ARCH_CONVERT))); 1906 XFS_DIR2_DATAPTR_TO_OFF(state->mp, INT_GET(lep->address, ARCH_CONVERT)));
1907 ASSERT(inum != INT_GET(dep->inumber, ARCH_CONVERT)); 1907 ASSERT(inum != INT_GET(dep->inumber, ARCH_CONVERT));
1908 /* 1908 /*
1909 * Fill in the new inode number and log the entry. 1909 * Fill in the new inode number and log the entry.
1910 */ 1910 */
1911 INT_SET(dep->inumber, ARCH_CONVERT, inum); 1911 INT_SET(dep->inumber, ARCH_CONVERT, inum);
1912 xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep); 1912 xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep);
1913 rval = 0; 1913 rval = 0;
1914 } 1914 }
1915 /* 1915 /*
1916 * Didn't find it, and we're holding a data block. Drop it. 1916 * Didn't find it, and we're holding a data block. Drop it.
1917 */ 1917 */
1918 else if (state->extravalid) { 1918 else if (state->extravalid) {
1919 xfs_da_brelse(args->trans, state->extrablk.bp); 1919 xfs_da_brelse(args->trans, state->extrablk.bp);
1920 state->extrablk.bp = NULL; 1920 state->extrablk.bp = NULL;
1921 } 1921 }
1922 /* 1922 /*
1923 * Release all the buffers in the cursor. 1923 * Release all the buffers in the cursor.
1924 */ 1924 */
1925 for (i = 0; i < state->path.active; i++) { 1925 for (i = 0; i < state->path.active; i++) {
1926 xfs_da_brelse(args->trans, state->path.blk[i].bp); 1926 xfs_da_brelse(args->trans, state->path.blk[i].bp);
1927 state->path.blk[i].bp = NULL; 1927 state->path.blk[i].bp = NULL;
1928 } 1928 }
1929 xfs_da_state_free(state); 1929 xfs_da_state_free(state);
1930 return rval; 1930 return rval;
1931 } 1931 }
1932 1932
1933 /* 1933 /*
1934 * Trim off a trailing empty freespace block. 1934 * Trim off a trailing empty freespace block.
1935 * Return (in rvalp) 1 if we did it, 0 if not. 1935 * Return (in rvalp) 1 if we did it, 0 if not.
1936 */ 1936 */
1937 int /* error */ 1937 int /* error */
1938 xfs_dir2_node_trim_free( 1938 xfs_dir2_node_trim_free(
1939 xfs_da_args_t *args, /* operation arguments */ 1939 xfs_da_args_t *args, /* operation arguments */
1940 xfs_fileoff_t fo, /* free block number */ 1940 xfs_fileoff_t fo, /* free block number */
1941 int *rvalp) /* out: did something */ 1941 int *rvalp) /* out: did something */
1942 { 1942 {
1943 xfs_dabuf_t *bp; /* freespace buffer */ 1943 xfs_dabuf_t *bp; /* freespace buffer */
1944 xfs_inode_t *dp; /* incore directory inode */ 1944 xfs_inode_t *dp; /* incore directory inode */
1945 int error; /* error return code */ 1945 int error; /* error return code */
1946 xfs_dir2_free_t *free; /* freespace structure */ 1946 xfs_dir2_free_t *free; /* freespace structure */
1947 xfs_mount_t *mp; /* filesystem mount point */ 1947 xfs_mount_t *mp; /* filesystem mount point */
1948 xfs_trans_t *tp; /* transaction pointer */ 1948 xfs_trans_t *tp; /* transaction pointer */
1949 1949
1950 dp = args->dp; 1950 dp = args->dp;
1951 mp = dp->i_mount; 1951 mp = dp->i_mount;
1952 tp = args->trans; 1952 tp = args->trans;
1953 /* 1953 /*
1954 * Read the freespace block. 1954 * Read the freespace block.
1955 */ 1955 */
1956 if (unlikely(error = xfs_da_read_buf(tp, dp, (xfs_dablk_t)fo, -2, &bp, 1956 if (unlikely(error = xfs_da_read_buf(tp, dp, (xfs_dablk_t)fo, -2, &bp,
1957 XFS_DATA_FORK))) { 1957 XFS_DATA_FORK))) {
1958 return error; 1958 return error;
1959 } 1959 }
1960 1960
1961 /* 1961 /*
1962 * There can be holes in freespace. If fo is a hole, there's 1962 * There can be holes in freespace. If fo is a hole, there's
1963 * nothing to do. 1963 * nothing to do.
1964 */ 1964 */
1965 if (bp == NULL) { 1965 if (bp == NULL) {
1966 return 0; 1966 return 0;
1967 } 1967 }
1968 free = bp->data; 1968 free = bp->data;
1969 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); 1969 ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
1970 /* 1970 /*
1971 * If there are used entries, there's nothing to do. 1971 * If there are used entries, there's nothing to do.
1972 */ 1972 */
1973 if (INT_GET(free->hdr.nused, ARCH_CONVERT) > 0) { 1973 if (INT_GET(free->hdr.nused, ARCH_CONVERT) > 0) {
1974 xfs_da_brelse(tp, bp); 1974 xfs_da_brelse(tp, bp);
1975 *rvalp = 0; 1975 *rvalp = 0;
1976 return 0; 1976 return 0;
1977 } 1977 }
1978 /* 1978 /*
1979 * Blow the block away. 1979 * Blow the block away.
1980 */ 1980 */
1981 if ((error = 1981 if ((error =
1982 xfs_dir2_shrink_inode(args, XFS_DIR2_DA_TO_DB(mp, (xfs_dablk_t)fo), 1982 xfs_dir2_shrink_inode(args, XFS_DIR2_DA_TO_DB(mp, (xfs_dablk_t)fo),
1983 bp))) { 1983 bp))) {
1984 /* 1984 /*
1985 * Can't fail with ENOSPC since that only happens with no 1985 * Can't fail with ENOSPC since that only happens with no
1986 * space reservation, when breaking up an extent into two 1986 * space reservation, when breaking up an extent into two
1987 * pieces. This is the last block of an extent. 1987 * pieces. This is the last block of an extent.
1988 */ 1988 */
1989 ASSERT(error != ENOSPC); 1989 ASSERT(error != ENOSPC);
1990 xfs_da_brelse(tp, bp); 1990 xfs_da_brelse(tp, bp);
1991 return error; 1991 return error;
1992 } 1992 }
1993 /* 1993 /*
1994 * Return that we succeeded. 1994 * Return that we succeeded.
1995 */ 1995 */
1996 *rvalp = 1; 1996 *rvalp = 1;
1997 return 0; 1997 return 0;
1998 } 1998 }
1999 1999