Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4 : * Copyright (c) 2013 Red Hat, Inc.
5 : * All Rights Reserved.
6 : */
7 : #include "xfs.h"
8 : #include "xfs_fs.h"
9 : #include "xfs_shared.h"
10 : #include "xfs_format.h"
11 : #include "xfs_log_format.h"
12 : #include "xfs_trans_resv.h"
13 : #include "xfs_sb.h"
14 : #include "xfs_mount.h"
15 : #include "xfs_da_format.h"
16 : #include "xfs_da_btree.h"
17 : #include "xfs_inode.h"
18 : #include "xfs_trans.h"
19 : #include "xfs_bmap_btree.h"
20 : #include "xfs_bmap.h"
21 : #include "xfs_attr_sf.h"
22 : #include "xfs_attr.h"
23 : #include "xfs_attr_remote.h"
24 : #include "xfs_attr_leaf.h"
25 : #include "xfs_error.h"
26 : #include "xfs_trace.h"
27 : #include "xfs_buf_item.h"
28 : #include "xfs_dir2.h"
29 : #include "xfs_log.h"
30 : #include "xfs_ag.h"
31 : #include "xfs_errortag.h"
32 :
33 :
34 : /*
35 : * xfs_attr_leaf.c
36 : *
37 : * Routines to implement leaf blocks of attributes as Btrees of hashed names.
38 : */
39 :
40 : /*========================================================================
41 : * Function prototypes for the kernel.
42 : *========================================================================*/
43 :
44 : /*
45 : * Routines used for growing the Btree.
46 : */
47 : STATIC int xfs_attr3_leaf_create(struct xfs_da_args *args,
48 : xfs_dablk_t which_block, struct xfs_buf **bpp);
49 : STATIC int xfs_attr3_leaf_add_work(struct xfs_buf *leaf_buffer,
50 : struct xfs_attr3_icleaf_hdr *ichdr,
51 : struct xfs_da_args *args, int freemap_index);
52 : STATIC void xfs_attr3_leaf_compact(struct xfs_da_args *args,
53 : struct xfs_attr3_icleaf_hdr *ichdr,
54 : struct xfs_buf *leaf_buffer);
55 : STATIC void xfs_attr3_leaf_rebalance(xfs_da_state_t *state,
56 : xfs_da_state_blk_t *blk1,
57 : xfs_da_state_blk_t *blk2);
58 : STATIC int xfs_attr3_leaf_figure_balance(xfs_da_state_t *state,
59 : xfs_da_state_blk_t *leaf_blk_1,
60 : struct xfs_attr3_icleaf_hdr *ichdr1,
61 : xfs_da_state_blk_t *leaf_blk_2,
62 : struct xfs_attr3_icleaf_hdr *ichdr2,
63 : int *number_entries_in_blk1,
64 : int *number_usedbytes_in_blk1);
65 :
66 : /*
67 : * Utility routines.
68 : */
69 : STATIC void xfs_attr3_leaf_moveents(struct xfs_da_args *args,
70 : struct xfs_attr_leafblock *src_leaf,
71 : struct xfs_attr3_icleaf_hdr *src_ichdr, int src_start,
72 : struct xfs_attr_leafblock *dst_leaf,
73 : struct xfs_attr3_icleaf_hdr *dst_ichdr, int dst_start,
74 : int move_count);
75 : STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
76 :
77 : /*
78 : * attr3 block 'firstused' conversion helpers.
79 : *
80 : * firstused refers to the offset of the first used byte of the nameval region
81 : * of an attr leaf block. The region starts at the tail of the block and expands
82 : * backwards towards the middle. As such, firstused is initialized to the block
83 : * size for an empty leaf block and is reduced from there.
84 : *
85 : * The attr3 block size is pegged to the fsb size and the maximum fsb is 64k.
86 : * The in-core firstused field is 32-bit and thus supports the maximum fsb size.
87 : * The on-disk field is only 16-bit, however, and overflows at 64k. Since this
88 : * only occurs at exactly 64k, we use zero as a magic on-disk value to represent
89 : * the attr block size. The following helpers manage the conversion between the
90 : * in-core and on-disk formats.
91 : */
92 :
93 : static void
94 1114236253 : xfs_attr3_leaf_firstused_from_disk(
95 : struct xfs_da_geometry *geo,
96 : struct xfs_attr3_icleaf_hdr *to,
97 : struct xfs_attr_leafblock *from)
98 : {
99 1114236253 : struct xfs_attr3_leaf_hdr *hdr3;
100 :
101 1114236253 : if (from->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)) {
102 1114236253 : hdr3 = (struct xfs_attr3_leaf_hdr *) from;
103 1114236253 : to->firstused = be16_to_cpu(hdr3->firstused);
104 : } else {
105 0 : to->firstused = be16_to_cpu(from->hdr.firstused);
106 : }
107 :
108 : /*
109 : * Convert from the magic fsb size value to actual blocksize. This
110 : * should only occur for empty blocks when the block size overflows
111 : * 16-bits.
112 : */
113 1114236253 : if (to->firstused == XFS_ATTR3_LEAF_NULLOFF) {
114 0 : ASSERT(!to->count && !to->usedbytes);
115 0 : ASSERT(geo->blksize > USHRT_MAX);
116 0 : to->firstused = geo->blksize;
117 : }
118 1114236253 : }
119 :
120 : static void
121 93107294 : xfs_attr3_leaf_firstused_to_disk(
122 : struct xfs_da_geometry *geo,
123 : struct xfs_attr_leafblock *to,
124 : struct xfs_attr3_icleaf_hdr *from)
125 : {
126 93107294 : struct xfs_attr3_leaf_hdr *hdr3;
127 93107294 : uint32_t firstused;
128 :
129 : /* magic value should only be seen on disk */
130 93107294 : ASSERT(from->firstused != XFS_ATTR3_LEAF_NULLOFF);
131 :
132 : /*
133 : * Scale down the 32-bit in-core firstused value to the 16-bit on-disk
134 : * value. This only overflows at the max supported value of 64k. Use the
135 : * magic on-disk value to represent block size in this case.
136 : */
137 93107294 : firstused = from->firstused;
138 93107294 : if (firstused > USHRT_MAX) {
139 0 : ASSERT(from->firstused == geo->blksize);
140 : firstused = XFS_ATTR3_LEAF_NULLOFF;
141 : }
142 :
143 93107294 : if (from->magic == XFS_ATTR3_LEAF_MAGIC) {
144 93107294 : hdr3 = (struct xfs_attr3_leaf_hdr *) to;
145 93107294 : hdr3->firstused = cpu_to_be16(firstused);
146 : } else {
147 0 : to->hdr.firstused = cpu_to_be16(firstused);
148 : }
149 93107294 : }
150 :
151 : void
152 1114331658 : xfs_attr3_leaf_hdr_from_disk(
153 : struct xfs_da_geometry *geo,
154 : struct xfs_attr3_icleaf_hdr *to,
155 : struct xfs_attr_leafblock *from)
156 : {
157 1114331658 : int i;
158 :
159 1114331658 : ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC) ||
160 : from->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC));
161 :
162 1114331658 : if (from->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)) {
163 1114331658 : struct xfs_attr3_leaf_hdr *hdr3 = (struct xfs_attr3_leaf_hdr *)from;
164 :
165 1114331658 : to->forw = be32_to_cpu(hdr3->info.hdr.forw);
166 1114331658 : to->back = be32_to_cpu(hdr3->info.hdr.back);
167 1114331658 : to->magic = be16_to_cpu(hdr3->info.hdr.magic);
168 1114331658 : to->count = be16_to_cpu(hdr3->count);
169 1114331658 : to->usedbytes = be16_to_cpu(hdr3->usedbytes);
170 1114331658 : xfs_attr3_leaf_firstused_from_disk(geo, to, from);
171 1114124231 : to->holes = hdr3->holes;
172 :
173 4454404701 : for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
174 3340733511 : to->freemap[i].base = be16_to_cpu(hdr3->freemap[i].base);
175 3340126031 : to->freemap[i].size = be16_to_cpu(hdr3->freemap[i].size);
176 : }
177 : return;
178 : }
179 0 : to->forw = be32_to_cpu(from->hdr.info.forw);
180 0 : to->back = be32_to_cpu(from->hdr.info.back);
181 0 : to->magic = be16_to_cpu(from->hdr.info.magic);
182 0 : to->count = be16_to_cpu(from->hdr.count);
183 0 : to->usedbytes = be16_to_cpu(from->hdr.usedbytes);
184 0 : xfs_attr3_leaf_firstused_from_disk(geo, to, from);
185 0 : to->holes = from->hdr.holes;
186 :
187 0 : for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
188 0 : to->freemap[i].base = be16_to_cpu(from->hdr.freemap[i].base);
189 0 : to->freemap[i].size = be16_to_cpu(from->hdr.freemap[i].size);
190 : }
191 : }
192 :
193 : void
194 93140670 : xfs_attr3_leaf_hdr_to_disk(
195 : struct xfs_da_geometry *geo,
196 : struct xfs_attr_leafblock *to,
197 : struct xfs_attr3_icleaf_hdr *from)
198 : {
199 93140670 : int i;
200 :
201 93140670 : ASSERT(from->magic == XFS_ATTR_LEAF_MAGIC ||
202 : from->magic == XFS_ATTR3_LEAF_MAGIC);
203 :
204 93140670 : if (from->magic == XFS_ATTR3_LEAF_MAGIC) {
205 93140670 : struct xfs_attr3_leaf_hdr *hdr3 = (struct xfs_attr3_leaf_hdr *)to;
206 :
207 93140670 : hdr3->info.hdr.forw = cpu_to_be32(from->forw);
208 93140670 : hdr3->info.hdr.back = cpu_to_be32(from->back);
209 93140670 : hdr3->info.hdr.magic = cpu_to_be16(from->magic);
210 93140670 : hdr3->count = cpu_to_be16(from->count);
211 93140670 : hdr3->usedbytes = cpu_to_be16(from->usedbytes);
212 93140670 : xfs_attr3_leaf_firstused_to_disk(geo, to, from);
213 93126673 : hdr3->holes = from->holes;
214 93126673 : hdr3->pad1 = 0;
215 :
216 372015005 : for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
217 279049123 : hdr3->freemap[i].base = cpu_to_be16(from->freemap[i].base);
218 278903940 : hdr3->freemap[i].size = cpu_to_be16(from->freemap[i].size);
219 : }
220 : return;
221 : }
222 0 : to->hdr.info.forw = cpu_to_be32(from->forw);
223 0 : to->hdr.info.back = cpu_to_be32(from->back);
224 0 : to->hdr.info.magic = cpu_to_be16(from->magic);
225 0 : to->hdr.count = cpu_to_be16(from->count);
226 0 : to->hdr.usedbytes = cpu_to_be16(from->usedbytes);
227 0 : xfs_attr3_leaf_firstused_to_disk(geo, to, from);
228 0 : to->hdr.holes = from->holes;
229 0 : to->hdr.pad1 = 0;
230 :
231 0 : for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
232 0 : to->hdr.freemap[i].base = cpu_to_be16(from->freemap[i].base);
233 0 : to->hdr.freemap[i].size = cpu_to_be16(from->freemap[i].size);
234 : }
235 : }
236 :
237 : static xfs_failaddr_t
238 246805715 : xfs_attr3_leaf_verify_entry(
239 : struct xfs_mount *mp,
240 : char *buf_end,
241 : struct xfs_attr_leafblock *leaf,
242 : struct xfs_attr3_icleaf_hdr *leafhdr,
243 : struct xfs_attr_leaf_entry *ent,
244 : int idx,
245 : __u32 *last_hashval)
246 : {
247 246805715 : struct xfs_attr_leaf_name_local *lentry;
248 246805715 : struct xfs_attr_leaf_name_remote *rentry;
249 246805715 : char *name_end;
250 246805715 : unsigned int nameidx;
251 246805715 : unsigned int namesize;
252 246805715 : __u32 hashval;
253 :
254 : /* hash order check */
255 246805715 : hashval = be32_to_cpu(ent->hashval);
256 246805715 : if (hashval < *last_hashval)
257 0 : return __this_address;
258 246805715 : *last_hashval = hashval;
259 :
260 246805715 : nameidx = be16_to_cpu(ent->nameidx);
261 246805715 : if (nameidx < leafhdr->firstused || nameidx >= mp->m_attr_geo->blksize)
262 0 : return __this_address;
263 :
264 : /*
265 : * Check the name information. The namelen fields are u8 so we can't
266 : * possibly exceed the maximum name length of 255 bytes.
267 : */
268 246805715 : if (ent->flags & XFS_ATTR_LOCAL) {
269 246802132 : lentry = xfs_attr3_leaf_name_local(leaf, idx);
270 246802132 : namesize = xfs_attr_leaf_entsize_local(lentry->namelen,
271 246802132 : be16_to_cpu(lentry->valuelen));
272 246802132 : name_end = (char *)lentry + namesize;
273 246802132 : if (lentry->namelen == 0)
274 0 : return __this_address;
275 : } else {
276 3583 : rentry = xfs_attr3_leaf_name_remote(leaf, idx);
277 3583 : namesize = xfs_attr_leaf_entsize_remote(rentry->namelen);
278 3583 : name_end = (char *)rentry + namesize;
279 3583 : if (rentry->namelen == 0)
280 0 : return __this_address;
281 3583 : if (!(ent->flags & XFS_ATTR_INCOMPLETE) &&
282 3583 : rentry->valueblk == 0)
283 0 : return __this_address;
284 : }
285 :
286 246805715 : if (name_end > buf_end)
287 0 : return __this_address;
288 :
289 : return NULL;
290 : }
291 :
292 : /*
293 : * Validate an attribute leaf block.
294 : *
295 : * Empty leaf blocks can occur under the following circumstances:
296 : *
297 : * 1. setxattr adds a new extended attribute to a file;
298 : * 2. The file has zero existing attributes;
299 : * 3. The attribute is too large to fit in the attribute fork;
300 : * 4. The attribute is small enough to fit in a leaf block;
301 : * 5. A log flush occurs after committing the transaction that creates
302 : * the (empty) leaf block; and
303 : * 6. The filesystem goes down after the log flush but before the new
304 : * attribute can be committed to the leaf block.
305 : *
306 : * Hence we need to ensure that we don't fail the validation purely
307 : * because the leaf is empty.
308 : */
309 : static xfs_failaddr_t
310 14349866 : xfs_attr3_leaf_verify(
311 : struct xfs_buf *bp)
312 : {
313 14349866 : struct xfs_attr3_icleaf_hdr ichdr;
314 14349866 : struct xfs_mount *mp = bp->b_mount;
315 14349866 : struct xfs_attr_leafblock *leaf = bp->b_addr;
316 14349866 : struct xfs_attr_leaf_entry *entries;
317 14349866 : struct xfs_attr_leaf_entry *ent;
318 14349866 : char *buf_end;
319 14349866 : uint32_t end; /* must be 32bit - see below */
320 14349866 : __u32 last_hashval = 0;
321 14349866 : int i;
322 14349866 : xfs_failaddr_t fa;
323 :
324 14349866 : xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
325 :
326 14352247 : fa = xfs_da3_blkinfo_verify(bp, bp->b_addr);
327 14348819 : if (fa)
328 : return fa;
329 :
330 : /*
331 : * firstused is the block offset of the first name info structure.
332 : * Make sure it doesn't go off the block or crash into the header.
333 : */
334 14348900 : if (ichdr.firstused > mp->m_attr_geo->blksize)
335 0 : return __this_address;
336 28697843 : if (ichdr.firstused < xfs_attr3_leaf_hdr_size(leaf))
337 0 : return __this_address;
338 :
339 : /* Make sure the entries array doesn't crash into the name info. */
340 14348900 : entries = xfs_attr3_leaf_entryp(bp->b_addr);
341 14348900 : if ((char *)&entries[ichdr.count] >
342 14348900 : (char *)bp->b_addr + ichdr.firstused)
343 0 : return __this_address;
344 :
345 : /*
346 : * NOTE: This verifier historically failed empty leaf buffers because
347 : * we expect the fork to be in another format. Empty attr fork format
348 : * conversions are possible during xattr set, however, and format
349 : * conversion is not atomic with the xattr set that triggers it. We
350 : * cannot assume leaf blocks are non-empty until that is addressed.
351 : */
352 14348900 : buf_end = (char *)bp->b_addr + mp->m_attr_geo->blksize;
353 261153834 : for (i = 0, ent = entries; i < ichdr.count; ent++, i++) {
354 246797158 : fa = xfs_attr3_leaf_verify_entry(mp, buf_end, leaf, &ichdr,
355 : ent, i, &last_hashval);
356 246804934 : if (fa)
357 0 : return fa;
358 : }
359 :
360 : /*
361 : * Quickly check the freemap information. Attribute data has to be
362 : * aligned to 4-byte boundaries, and likewise for the free space.
363 : *
364 : * Note that for 64k block size filesystems, the freemap entries cannot
365 : * overflow as they are only be16 fields. However, when checking end
366 : * pointer of the freemap, we have to be careful to detect overflows and
367 : * so use uint32_t for those checks.
368 : */
369 57424422 : for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
370 43067894 : if (ichdr.freemap[i].base > mp->m_attr_geo->blksize)
371 0 : return __this_address;
372 43068436 : if (ichdr.freemap[i].base & 0x3)
373 0 : return __this_address;
374 43068523 : if (ichdr.freemap[i].size > mp->m_attr_geo->blksize)
375 0 : return __this_address;
376 43068092 : if (ichdr.freemap[i].size & 0x3)
377 0 : return __this_address;
378 :
379 : /* be care of 16 bit overflows here */
380 43067777 : end = (uint32_t)ichdr.freemap[i].base + ichdr.freemap[i].size;
381 43067585 : if (end < ichdr.freemap[i].base)
382 0 : return __this_address;
383 43067746 : if (end > mp->m_attr_geo->blksize)
384 0 : return __this_address;
385 : }
386 :
387 : return NULL;
388 : }
389 :
390 : static void
391 12545287 : xfs_attr3_leaf_write_verify(
392 : struct xfs_buf *bp)
393 : {
394 12545287 : struct xfs_mount *mp = bp->b_mount;
395 12545287 : struct xfs_buf_log_item *bip = bp->b_log_item;
396 12545287 : struct xfs_attr3_leaf_hdr *hdr3 = bp->b_addr;
397 12545287 : xfs_failaddr_t fa;
398 :
399 12545287 : fa = xfs_attr3_leaf_verify(bp);
400 12545287 : if (fa) {
401 0 : xfs_verifier_error(bp, -EFSCORRUPTED, fa);
402 0 : return;
403 : }
404 :
405 12545287 : if (!xfs_has_crc(mp))
406 : return;
407 :
408 12545287 : if (bip)
409 12545287 : hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn);
410 :
411 12545287 : xfs_buf_update_cksum(bp, XFS_ATTR3_LEAF_CRC_OFF);
412 : }
413 :
414 : /*
415 : * leaf/node format detection on trees is sketchy, so a node read can be done on
416 : * leaf level blocks when detection identifies the tree as a node format tree
417 : * incorrectly. In this case, we need to swap the verifier to match the correct
418 : * format of the block being read.
419 : */
420 : static void
421 84812 : xfs_attr3_leaf_read_verify(
422 : struct xfs_buf *bp)
423 : {
424 84812 : struct xfs_mount *mp = bp->b_mount;
425 84812 : xfs_failaddr_t fa;
426 :
427 169624 : if (xfs_has_crc(mp) &&
428 : !xfs_buf_verify_cksum(bp, XFS_ATTR3_LEAF_CRC_OFF))
429 21 : xfs_verifier_error(bp, -EFSBADCRC, __this_address);
430 : else {
431 84791 : fa = xfs_attr3_leaf_verify(bp);
432 84791 : if (fa)
433 0 : xfs_verifier_error(bp, -EFSCORRUPTED, fa);
434 : }
435 84812 : }
436 :
437 : const struct xfs_buf_ops xfs_attr3_leaf_buf_ops = {
438 : .name = "xfs_attr3_leaf",
439 : .magic16 = { cpu_to_be16(XFS_ATTR_LEAF_MAGIC),
440 : cpu_to_be16(XFS_ATTR3_LEAF_MAGIC) },
441 : .verify_read = xfs_attr3_leaf_read_verify,
442 : .verify_write = xfs_attr3_leaf_write_verify,
443 : .verify_struct = xfs_attr3_leaf_verify,
444 : };
445 :
446 : int
447 205528346 : xfs_attr3_leaf_read(
448 : struct xfs_trans *tp,
449 : struct xfs_inode *dp,
450 : xfs_dablk_t bno,
451 : struct xfs_buf **bpp)
452 : {
453 205528346 : int err;
454 :
455 205528346 : err = xfs_da_read_buf(tp, dp, bno, 0, bpp, XFS_ATTR_FORK,
456 : &xfs_attr3_leaf_buf_ops);
457 205721851 : if (!err && tp && *bpp)
458 165231848 : xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_ATTR_LEAF_BUF);
459 205579027 : return err;
460 : }
461 :
462 : /*========================================================================
463 : * Namespace helper routines
464 : *========================================================================*/
465 :
466 : /*
467 : * If we are in log recovery, then we want the lookup to ignore the INCOMPLETE
468 : * flag on disk - if there's an incomplete attr then recovery needs to tear it
469 : * down. If there's no incomplete attr, then recovery needs to tear that attr
470 : * down to replace it with the attr that has been logged. In this case, the
471 : * INCOMPLETE flag will not be set in attr->attr_filter, but rather
472 : * XFS_DA_OP_RECOVERY will be set in args->op_flags.
473 : */
474 : static bool
475 3250524573 : xfs_attr_match(
476 : struct xfs_da_args *args,
477 : uint8_t namelen,
478 : unsigned char *name,
479 : int flags)
480 : {
481 :
482 3250524573 : if (args->namelen != namelen)
483 : return false;
484 6405094216 : if (memcmp(args->name, name, namelen) != 0)
485 : return false;
486 :
487 : /* Recovery ignores the INCOMPLETE flag. */
488 114695837 : if ((args->op_flags & XFS_DA_OP_RECOVERY) &&
489 242 : args->attr_filter == (flags & XFS_ATTR_NSP_ONDISK_MASK))
490 : return true;
491 :
492 : /* All remaining matches need to be filtered by INCOMPLETE state. */
493 114695672 : if (args->attr_filter !=
494 114695672 : (flags & (XFS_ATTR_NSP_ONDISK_MASK | XFS_ATTR_INCOMPLETE)))
495 234158 : return false;
496 : return true;
497 : }
498 :
499 : static int
500 28650516 : xfs_attr_copy_value(
501 : struct xfs_da_args *args,
502 : unsigned char *value,
503 : int valuelen)
504 : {
505 : /*
506 : * No copy if all we have to do is get the length
507 : */
508 28650516 : if (!args->valuelen) {
509 4620637 : args->valuelen = valuelen;
510 4620637 : return 0;
511 : }
512 :
513 : /*
514 : * No copy if the length of the existing buffer is too small
515 : */
516 24029879 : if (args->valuelen < valuelen) {
517 0 : args->valuelen = valuelen;
518 0 : return -ERANGE;
519 : }
520 :
521 24029879 : if (!args->value) {
522 1583 : args->value = kvmalloc(valuelen, GFP_KERNEL | __GFP_NOLOCKDEP);
523 1583 : if (!args->value)
524 : return -ENOMEM;
525 : }
526 24029879 : args->valuelen = valuelen;
527 :
528 : /* remote block xattr requires IO for copy-in */
529 24029879 : if (args->rmtblkno)
530 784 : return xfs_attr_rmtval_get(args);
531 :
532 : /*
533 : * This is to prevent a GCC warning because the remote xattr case
534 : * doesn't have a value to pass in. In that case, we never reach here,
535 : * but GCC can't work that out and so throws a "passing NULL to
536 : * memcpy" warning.
537 : */
538 24029095 : if (!value)
539 : return -EINVAL;
540 48058190 : memcpy(args->value, value, valuelen);
541 24029095 : return 0;
542 : }
543 :
544 : /*========================================================================
545 : * External routines when attribute fork size < XFS_LITINO(mp).
546 : *========================================================================*/
547 :
548 : /*
549 : * Query whether the total requested number of attr fork bytes of extended
550 : * attribute space will be able to fit inline.
551 : *
552 : * Returns zero if not, else the i_forkoff fork offset to be used in the
553 : * literal area for attribute data once the new bytes have been added.
554 : *
555 : * i_forkoff must be 8 byte aligned, hence is stored as a >>3 value;
556 : * special case for dev/uuid inodes, they have fixed size data forks.
557 : */
558 : int
559 67181148 : xfs_attr_shortform_bytesfit(
560 : struct xfs_inode *dp,
561 : int bytes)
562 : {
563 67181148 : struct xfs_mount *mp = dp->i_mount;
564 67181148 : int64_t dsize;
565 67181148 : int minforkoff;
566 67181148 : int maxforkoff;
567 67181148 : int offset;
568 :
569 : /*
570 : * Check if the new size could fit at all first:
571 : */
572 67181203 : if (bytes > XFS_LITINO(mp))
573 : return 0;
574 :
575 : /* rounded down */
576 41202240 : offset = (XFS_LITINO(mp) - bytes) >> 3;
577 :
578 41202240 : if (dp->i_df.if_format == XFS_DINODE_FMT_DEV) {
579 594 : minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
580 594 : return (offset >= minforkoff) ? minforkoff : 0;
581 : }
582 :
583 : /*
584 : * If the requested numbers of bytes is smaller or equal to the
585 : * current attribute fork size we can always proceed.
586 : *
587 : * Note that if_bytes in the data fork might actually be larger than
588 : * the current data fork size is due to delalloc extents. In that
589 : * case either the extent count will go down when they are converted
590 : * to real extents, or the delalloc conversion will take care of the
591 : * literal area rebalancing.
592 : */
593 41201646 : if (bytes <= xfs_inode_attr_fork_size(dp))
594 22247645 : return dp->i_forkoff;
595 :
596 : /*
597 : * For attr2 we can try to move the forkoff if there is space in the
598 : * literal area, but for the old format we are done if there is no
599 : * space in the fixed attribute fork.
600 : */
601 18954001 : if (!xfs_has_attr2(mp))
602 : return 0;
603 :
604 18954001 : dsize = dp->i_df.if_bytes;
605 :
606 18954001 : switch (dp->i_df.if_format) {
607 17257503 : case XFS_DINODE_FMT_EXTENTS:
608 : /*
609 : * If there is no attr fork and the data fork is extents,
610 : * determine if creating the default attr fork will result
611 : * in the extents form migrating to btree. If so, the
612 : * minimum offset only needs to be the space required for
613 : * the btree root.
614 : */
615 17257503 : if (!dp->i_forkoff && dp->i_df.if_bytes >
616 3866382 : xfs_default_attroffset(dp))
617 106801 : dsize = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
618 : break;
619 109632 : case XFS_DINODE_FMT_BTREE:
620 : /*
621 : * If we have a data btree then keep forkoff if we have one,
622 : * otherwise we are adding a new attr, so then we set
623 : * minforkoff to where the btree root can finish so we have
624 : * plenty of room for attrs
625 : */
626 109632 : if (dp->i_forkoff) {
627 64383 : if (offset < dp->i_forkoff)
628 : return 0;
629 0 : return dp->i_forkoff;
630 : }
631 45249 : dsize = XFS_BMAP_BROOT_SPACE(mp, dp->i_df.if_broot);
632 45249 : break;
633 : }
634 :
635 : /*
636 : * A data fork btree root must have space for at least
637 : * MINDBTPTRS key/ptr pairs if the data fork is small or empty.
638 : */
639 18889404 : minforkoff = max_t(int64_t, dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS));
640 18889404 : minforkoff = roundup(minforkoff, 8) >> 3;
641 :
642 : /* attr fork btree root can have at least this many key/ptr pairs */
643 18889404 : maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS);
644 18889404 : maxforkoff = maxforkoff >> 3; /* rounded down */
645 :
646 18889404 : if (offset >= maxforkoff)
647 : return maxforkoff;
648 17313372 : if (offset >= minforkoff)
649 13426745 : return offset;
650 : return 0;
651 : }
652 :
653 : /*
654 : * Switch on the ATTR2 superblock bit (implies also FEATURES2) unless:
655 : * - noattr2 mount option is set,
656 : * - on-disk version bit says it is already set, or
657 : * - the attr2 mount option is not set to enable automatic upgrade from attr1.
658 : */
659 : STATIC void
660 38559142 : xfs_sbversion_add_attr2(
661 : struct xfs_mount *mp,
662 : struct xfs_trans *tp)
663 : {
664 38559142 : if (xfs_has_noattr2(mp))
665 : return;
666 38559142 : if (mp->m_sb.sb_features2 & XFS_SB_VERSION2_ATTR2BIT)
667 : return;
668 0 : if (!xfs_has_attr2(mp))
669 : return;
670 :
671 0 : spin_lock(&mp->m_sb_lock);
672 0 : xfs_add_attr2(mp);
673 0 : spin_unlock(&mp->m_sb_lock);
674 0 : xfs_log_sb(tp);
675 : }
676 :
677 : /*
678 : * Create the initial contents of a shortform attribute list.
679 : */
680 : void
681 6308149 : xfs_attr_shortform_create(
682 : struct xfs_da_args *args)
683 : {
684 6308149 : struct xfs_inode *dp = args->dp;
685 6308149 : struct xfs_ifork *ifp = &dp->i_af;
686 6308149 : struct xfs_attr_sf_hdr *hdr;
687 :
688 6308149 : trace_xfs_attr_sf_create(args);
689 :
690 6307694 : ASSERT(ifp->if_bytes == 0);
691 6307694 : if (ifp->if_format == XFS_DINODE_FMT_EXTENTS)
692 6307735 : ifp->if_format = XFS_DINODE_FMT_LOCAL;
693 6307694 : xfs_idata_realloc(dp, sizeof(*hdr), XFS_ATTR_FORK);
694 6308023 : hdr = (struct xfs_attr_sf_hdr *)ifp->if_u1.if_data;
695 6308023 : memset(hdr, 0, sizeof(*hdr));
696 6308023 : hdr->totsize = cpu_to_be16(sizeof(*hdr));
697 6308023 : xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
698 6309584 : }
699 :
700 : /*
701 : * Return -EEXIST if attr is found, or -ENOATTR if not
702 : * args: args containing attribute name and namelen
703 : * sfep: If not null, pointer will be set to the last attr entry found on
704 : -EEXIST. On -ENOATTR pointer is left at the last entry in the list
705 : * basep: If not null, pointer is set to the byte offset of the entry in the
706 : * list on -EEXIST. On -ENOATTR, pointer is left at the byte offset of
707 : * the last entry in the list
708 : */
709 : int
710 68229455 : xfs_attr_sf_findname(
711 : struct xfs_da_args *args,
712 : struct xfs_attr_sf_entry **sfep,
713 : unsigned int *basep)
714 : {
715 68229455 : struct xfs_attr_shortform *sf;
716 68229455 : struct xfs_attr_sf_entry *sfe;
717 68229455 : unsigned int base = sizeof(struct xfs_attr_sf_hdr);
718 68229455 : int size = 0;
719 68229455 : int end;
720 68229455 : int i;
721 :
722 68229455 : sf = (struct xfs_attr_shortform *)args->dp->i_af.if_u1.if_data;
723 68229455 : sfe = &sf->list[0];
724 68229455 : end = sf->hdr.count;
725 195015445 : for (i = 0; i < end; sfe = xfs_attr_sf_nextentry(sfe),
726 126785990 : base += size, i++) {
727 148349546 : size = xfs_attr_sf_entsize(sfe);
728 148379416 : if (!xfs_attr_match(args, sfe->namelen, sfe->nameval,
729 148349546 : sfe->flags))
730 126785990 : continue;
731 : break;
732 : }
733 :
734 68259325 : if (sfep != NULL)
735 38551845 : *sfep = sfe;
736 :
737 68259325 : if (basep != NULL)
738 10778034 : *basep = base;
739 :
740 68259325 : if (i == end)
741 46665382 : return -ENOATTR;
742 : return -EEXIST;
743 : }
744 :
745 : /*
746 : * Add a name/value pair to the shortform attribute list.
747 : * Overflow from the inode has already been checked for.
748 : */
749 : void
750 27778576 : xfs_attr_shortform_add(
751 : struct xfs_da_args *args,
752 : int forkoff)
753 : {
754 27778576 : struct xfs_attr_shortform *sf;
755 27778576 : struct xfs_attr_sf_entry *sfe;
756 27778576 : int offset, size;
757 27778576 : struct xfs_mount *mp;
758 27778576 : struct xfs_inode *dp;
759 27778576 : struct xfs_ifork *ifp;
760 :
761 27778576 : trace_xfs_attr_sf_add(args);
762 :
763 27775653 : dp = args->dp;
764 27775653 : mp = dp->i_mount;
765 27775653 : dp->i_forkoff = forkoff;
766 :
767 27775653 : ifp = &dp->i_af;
768 27775653 : ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
769 27775653 : sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
770 27775653 : if (xfs_attr_sf_findname(args, &sfe, NULL) == -EEXIST)
771 0 : ASSERT(0);
772 :
773 27782251 : offset = (char *)sfe - (char *)sf;
774 27782251 : size = xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
775 27782251 : xfs_idata_realloc(dp, size, XFS_ATTR_FORK);
776 27785836 : sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
777 27785836 : sfe = (struct xfs_attr_sf_entry *)((char *)sf + offset);
778 :
779 27785836 : sfe->namelen = args->namelen;
780 27785836 : sfe->valuelen = args->valuelen;
781 27785836 : sfe->flags = args->attr_filter;
782 55571672 : memcpy(sfe->nameval, args->name, args->namelen);
783 55571672 : memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
784 27785836 : sf->hdr.count++;
785 27785836 : be16_add_cpu(&sf->hdr.totsize, size);
786 27785836 : xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
787 :
788 27788794 : xfs_sbversion_add_attr2(mp, args->trans);
789 27786851 : }
790 :
791 : /*
792 : * After the last attribute is removed revert to original inode format,
793 : * making all literal area available to the data fork once more.
794 : */
795 : void
796 2348240 : xfs_attr_fork_remove(
797 : struct xfs_inode *ip,
798 : struct xfs_trans *tp)
799 : {
800 2348240 : ASSERT(ip->i_af.if_nextents == 0);
801 :
802 2348240 : xfs_ifork_zap_attr(ip);
803 2346589 : ip->i_forkoff = 0;
804 2346589 : xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
805 2349256 : }
806 :
807 : /*
808 : * Remove an attribute from the shortform attribute list structure.
809 : */
810 : int
811 10771236 : xfs_attr_sf_removename(
812 : struct xfs_da_args *args)
813 : {
814 10771236 : struct xfs_attr_shortform *sf;
815 10771236 : struct xfs_attr_sf_entry *sfe;
816 10771236 : int size = 0, end, totsize;
817 10771236 : unsigned int base;
818 10771236 : struct xfs_mount *mp;
819 10771236 : struct xfs_inode *dp;
820 10771236 : int error;
821 :
822 10771236 : trace_xfs_attr_sf_remove(args);
823 :
824 10769934 : dp = args->dp;
825 10769934 : mp = dp->i_mount;
826 10769934 : sf = (struct xfs_attr_shortform *)dp->i_af.if_u1.if_data;
827 :
828 10769934 : error = xfs_attr_sf_findname(args, &sfe, &base);
829 :
830 : /*
831 : * If we are recovering an operation, finding nothing to
832 : * remove is not an error - it just means there was nothing
833 : * to clean up.
834 : */
835 10773776 : if (error == -ENOATTR && (args->op_flags & XFS_DA_OP_RECOVERY))
836 : return 0;
837 10773743 : if (error != -EEXIST)
838 : return error;
839 10773743 : size = xfs_attr_sf_entsize(sfe);
840 :
841 : /*
842 : * Fix up the attribute fork data, covering the hole
843 : */
844 10773743 : end = base + size;
845 10773743 : totsize = be16_to_cpu(sf->hdr.totsize);
846 10773743 : if (end != totsize)
847 9857002 : memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end);
848 10773743 : sf->hdr.count--;
849 10773743 : be16_add_cpu(&sf->hdr.totsize, -size);
850 :
851 : /*
852 : * Fix up the start offset of the attribute fork
853 : */
854 10773743 : totsize -= size;
855 10773743 : if (totsize == sizeof(xfs_attr_sf_hdr_t) && xfs_has_attr2(mp) &&
856 2635401 : (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) &&
857 2576962 : !(args->op_flags & (XFS_DA_OP_ADDNAME | XFS_DA_OP_REPLACE))) {
858 901886 : xfs_attr_fork_remove(dp, args->trans);
859 : } else {
860 9871857 : xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
861 9872217 : dp->i_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
862 9870219 : ASSERT(dp->i_forkoff);
863 9870219 : ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) ||
864 : (args->op_flags & XFS_DA_OP_ADDNAME) ||
865 : !xfs_has_attr2(mp) ||
866 : dp->i_df.if_format == XFS_DINODE_FMT_BTREE);
867 9870219 : xfs_trans_log_inode(args->trans, dp,
868 : XFS_ILOG_CORE | XFS_ILOG_ADATA);
869 : }
870 :
871 10775195 : xfs_sbversion_add_attr2(mp, args->trans);
872 :
873 10775195 : return 0;
874 : }
875 :
876 : /*
877 : * Look up a name in a shortform attribute list structure.
878 : */
879 : /*ARGSUSED*/
880 : int
881 24030430 : xfs_attr_shortform_lookup(xfs_da_args_t *args)
882 : {
883 24030430 : struct xfs_attr_shortform *sf;
884 24030430 : struct xfs_attr_sf_entry *sfe;
885 24030430 : int i;
886 24030430 : struct xfs_ifork *ifp;
887 :
888 24030430 : trace_xfs_attr_sf_lookup(args);
889 :
890 24026716 : ifp = &args->dp->i_af;
891 24026716 : ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
892 24026716 : sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
893 24026716 : sfe = &sf->list[0];
894 68533357 : for (i = 0; i < sf->hdr.count;
895 44506641 : sfe = xfs_attr_sf_nextentry(sfe), i++) {
896 49847330 : if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
897 49824065 : sfe->flags))
898 : return -EEXIST;
899 : }
900 : return -ENOATTR;
901 : }
902 :
903 : /*
904 : * Retrieve the attribute value and length.
905 : *
906 : * If args->valuelen is zero, only the length needs to be returned. Unlike a
907 : * lookup, we only return an error if the attribute does not exist or we can't
908 : * retrieve the value.
909 : */
910 : int
911 25734369 : xfs_attr_shortform_getvalue(
912 : struct xfs_da_args *args)
913 : {
914 25734369 : struct xfs_attr_shortform *sf;
915 25734369 : struct xfs_attr_sf_entry *sfe;
916 25734369 : int i;
917 :
918 25734369 : ASSERT(args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL);
919 25734369 : sf = (struct xfs_attr_shortform *)args->dp->i_af.if_u1.if_data;
920 25734369 : sfe = &sf->list[0];
921 37496408 : for (i = 0; i < sf->hdr.count;
922 11762039 : sfe = xfs_attr_sf_nextentry(sfe), i++) {
923 34701715 : if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
924 34710545 : sfe->flags))
925 22939676 : return xfs_attr_copy_value(args,
926 22939676 : &sfe->nameval[args->namelen], sfe->valuelen);
927 : }
928 : return -ENOATTR;
929 : }
930 :
931 : /* Convert from using the shortform to the leaf format. */
932 : int
933 2844249 : xfs_attr_shortform_to_leaf(
934 : struct xfs_da_args *args)
935 : {
936 2844249 : struct xfs_inode *dp;
937 2844249 : struct xfs_attr_shortform *sf;
938 2844249 : struct xfs_attr_sf_entry *sfe;
939 2844249 : struct xfs_da_args nargs;
940 2844249 : char *tmpbuffer;
941 2844249 : int error, i, size;
942 2844249 : xfs_dablk_t blkno;
943 2844249 : struct xfs_buf *bp;
944 2844249 : struct xfs_ifork *ifp;
945 :
946 2844249 : trace_xfs_attr_sf_to_leaf(args);
947 :
948 2844080 : dp = args->dp;
949 2844080 : ifp = &dp->i_af;
950 2844080 : sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
951 2844080 : size = be16_to_cpu(sf->hdr.totsize);
952 2844080 : tmpbuffer = kmem_alloc(size, 0);
953 2844550 : ASSERT(tmpbuffer != NULL);
954 5689100 : memcpy(tmpbuffer, ifp->if_u1.if_data, size);
955 2844550 : sf = (struct xfs_attr_shortform *)tmpbuffer;
956 :
957 2844550 : xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
958 2844561 : xfs_bmap_local_to_extents_empty(args->trans, dp, XFS_ATTR_FORK);
959 :
960 2844615 : bp = NULL;
961 2844615 : error = xfs_da_grow_inode(args, &blkno);
962 2843339 : if (error)
963 7 : goto out;
964 :
965 2843332 : ASSERT(blkno == 0);
966 2843332 : error = xfs_attr3_leaf_create(args, blkno, &bp);
967 2840948 : if (error)
968 0 : goto out;
969 :
970 2840948 : memset((char *)&nargs, 0, sizeof(nargs));
971 2840948 : nargs.dp = dp;
972 2840948 : nargs.geo = args->geo;
973 2840948 : nargs.total = args->total;
974 2840948 : nargs.whichfork = XFS_ATTR_FORK;
975 2840948 : nargs.trans = args->trans;
976 2840948 : nargs.op_flags = XFS_DA_OP_OKNOENT;
977 :
978 2840948 : sfe = &sf->list[0];
979 15333716 : for (i = 0; i < sf->hdr.count; i++) {
980 12489068 : nargs.name = sfe->nameval;
981 12489068 : nargs.namelen = sfe->namelen;
982 12489068 : nargs.value = &sfe->nameval[nargs.namelen];
983 12489068 : nargs.valuelen = sfe->valuelen;
984 24976060 : nargs.hashval = xfs_da_hashname(sfe->nameval,
985 12489068 : sfe->namelen);
986 12486992 : nargs.attr_filter = sfe->flags & XFS_ATTR_NSP_ONDISK_MASK;
987 12486992 : error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */
988 12484800 : ASSERT(error == -ENOATTR);
989 12484800 : error = xfs_attr3_leaf_add(bp, &nargs);
990 12492768 : ASSERT(error != -ENOSPC);
991 12492768 : if (error)
992 0 : goto out;
993 12492768 : sfe = xfs_attr_sf_nextentry(sfe);
994 : }
995 : error = 0;
996 2844655 : out:
997 2844655 : kmem_free(tmpbuffer);
998 2844378 : return error;
999 : }
1000 :
1001 : /*
1002 : * Check a leaf attribute block to see if all the entries would fit into
1003 : * a shortform attribute list.
1004 : */
1005 : int
1006 28511392 : xfs_attr_shortform_allfit(
1007 : struct xfs_buf *bp,
1008 : struct xfs_inode *dp)
1009 : {
1010 28511392 : struct xfs_attr_leafblock *leaf;
1011 28511392 : struct xfs_attr_leaf_entry *entry;
1012 28511392 : xfs_attr_leaf_name_local_t *name_loc;
1013 28511392 : struct xfs_attr3_icleaf_hdr leafhdr;
1014 28511392 : int bytes;
1015 28511392 : int i;
1016 28511392 : struct xfs_mount *mp = bp->b_mount;
1017 :
1018 28511392 : leaf = bp->b_addr;
1019 28511392 : xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);
1020 28529091 : entry = xfs_attr3_leaf_entryp(leaf);
1021 :
1022 28529091 : bytes = sizeof(struct xfs_attr_sf_hdr);
1023 519766614 : for (i = 0; i < leafhdr.count; entry++, i++) {
1024 491237567 : if (entry->flags & XFS_ATTR_INCOMPLETE)
1025 0 : continue; /* don't copy partial entries */
1026 491237567 : if (!(entry->flags & XFS_ATTR_LOCAL))
1027 : return 0;
1028 491237567 : name_loc = xfs_attr3_leaf_name_local(leaf, i);
1029 491237567 : if (name_loc->namelen >= XFS_ATTR_SF_ENTSIZE_MAX)
1030 : return 0;
1031 491237567 : if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX)
1032 : return 0;
1033 491237523 : bytes += xfs_attr_sf_entsize_byname(name_loc->namelen,
1034 : be16_to_cpu(name_loc->valuelen));
1035 : }
1036 28529047 : if (xfs_has_attr2(dp->i_mount) &&
1037 28529047 : (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) &&
1038 : (bytes == sizeof(struct xfs_attr_sf_hdr)))
1039 : return -1;
1040 28528709 : return xfs_attr_shortform_bytesfit(dp, bytes);
1041 : }
1042 :
1043 : /* Verify the consistency of an inline attribute fork. */
1044 : xfs_failaddr_t
1045 64453098 : xfs_attr_shortform_verify(
1046 : struct xfs_inode *ip)
1047 : {
1048 64453098 : struct xfs_attr_shortform *sfp;
1049 64453098 : struct xfs_attr_sf_entry *sfep;
1050 64453098 : struct xfs_attr_sf_entry *next_sfep;
1051 64453098 : char *endp;
1052 64453098 : struct xfs_ifork *ifp;
1053 64453098 : int i;
1054 64453098 : int64_t size;
1055 :
1056 64453098 : ASSERT(ip->i_af.if_format == XFS_DINODE_FMT_LOCAL);
1057 64453098 : ifp = xfs_ifork_ptr(ip, XFS_ATTR_FORK);
1058 64453098 : sfp = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
1059 64453098 : size = ifp->if_bytes;
1060 :
1061 : /*
1062 : * Give up if the attribute is way too short.
1063 : */
1064 64453098 : if (size < sizeof(struct xfs_attr_sf_hdr))
1065 0 : return __this_address;
1066 :
1067 64453098 : endp = (char *)sfp + size;
1068 :
1069 : /* Check all reported entries */
1070 64453098 : sfep = &sfp->list[0];
1071 153434497 : for (i = 0; i < sfp->hdr.count; i++) {
1072 : /*
1073 : * struct xfs_attr_sf_entry has a variable length.
1074 : * Check the fixed-offset parts of the structure are
1075 : * within the data buffer.
1076 : * xfs_attr_sf_entry is defined with a 1-byte variable
1077 : * array at the end, so we must subtract that off.
1078 : */
1079 88981399 : if (((char *)sfep + sizeof(*sfep)) >= endp)
1080 0 : return __this_address;
1081 :
1082 : /* Don't allow names with known bad length. */
1083 88981399 : if (sfep->namelen == 0)
1084 0 : return __this_address;
1085 :
1086 : /*
1087 : * Check that the variable-length part of the structure is
1088 : * within the data buffer. The next entry starts after the
1089 : * name component, so nextentry is an acceptable test.
1090 : */
1091 88981399 : next_sfep = xfs_attr_sf_nextentry(sfep);
1092 88981399 : if ((char *)next_sfep > endp)
1093 0 : return __this_address;
1094 :
1095 : /*
1096 : * Check for unknown flags. Short form doesn't support
1097 : * the incomplete or local bits, so we can use the namespace
1098 : * mask here.
1099 : */
1100 88981399 : if (sfep->flags & ~XFS_ATTR_NSP_ONDISK_MASK)
1101 0 : return __this_address;
1102 :
1103 : /*
1104 : * Check for invalid namespace combinations. We only allow
1105 : * one namespace flag per xattr, so we can just count the
1106 : * bits (i.e. hweight) here.
1107 : */
1108 88981399 : if (hweight8(sfep->flags & XFS_ATTR_NSP_ONDISK_MASK) > 1)
1109 0 : return __this_address;
1110 :
1111 88981399 : sfep = next_sfep;
1112 : }
1113 64453098 : if ((void *)sfep != (void *)endp)
1114 0 : return __this_address;
1115 :
1116 : return NULL;
1117 : }
1118 :
1119 : /*
1120 : * Convert a leaf attribute list to shortform attribute list
1121 : */
1122 : int
1123 1420060 : xfs_attr3_leaf_to_shortform(
1124 : struct xfs_buf *bp,
1125 : struct xfs_da_args *args,
1126 : int forkoff)
1127 : {
1128 1420060 : struct xfs_attr_leafblock *leaf;
1129 1420060 : struct xfs_attr3_icleaf_hdr ichdr;
1130 1420060 : struct xfs_attr_leaf_entry *entry;
1131 1420060 : struct xfs_attr_leaf_name_local *name_loc;
1132 1420060 : struct xfs_da_args nargs;
1133 1420060 : struct xfs_inode *dp = args->dp;
1134 1420060 : char *tmpbuffer;
1135 1420060 : int error;
1136 1420060 : int i;
1137 :
1138 1420060 : trace_xfs_attr_leaf_to_sf(args);
1139 :
1140 1419951 : tmpbuffer = kmem_alloc(args->geo->blksize, 0);
1141 1420166 : if (!tmpbuffer)
1142 : return -ENOMEM;
1143 :
1144 2840332 : memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
1145 :
1146 1420166 : leaf = (xfs_attr_leafblock_t *)tmpbuffer;
1147 1420166 : xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
1148 1420177 : entry = xfs_attr3_leaf_entryp(leaf);
1149 :
1150 : /* XXX (dgc): buffer is about to be marked stale - why zero it? */
1151 1420177 : memset(bp->b_addr, 0, args->geo->blksize);
1152 :
1153 : /*
1154 : * Clean out the prior contents of the attribute list.
1155 : */
1156 1420177 : error = xfs_da_shrink_inode(args, 0, bp);
1157 1420107 : if (error)
1158 0 : goto out;
1159 :
1160 1420107 : if (forkoff == -1) {
1161 : /*
1162 : * Don't remove the attr fork if this operation is the first
1163 : * part of a attr replace operations. We're going to add a new
1164 : * attr immediately, so we need to keep the attr fork around in
1165 : * this case.
1166 : */
1167 338 : if (!(args->op_flags & XFS_DA_OP_REPLACE)) {
1168 315 : ASSERT(xfs_has_attr2(dp->i_mount));
1169 315 : ASSERT(dp->i_df.if_format != XFS_DINODE_FMT_BTREE);
1170 315 : xfs_attr_fork_remove(dp, args->trans);
1171 : }
1172 338 : goto out;
1173 : }
1174 :
1175 1419769 : xfs_attr_shortform_create(args);
1176 :
1177 : /*
1178 : * Copy the attributes
1179 : */
1180 1419764 : memset((char *)&nargs, 0, sizeof(nargs));
1181 1419764 : nargs.geo = args->geo;
1182 1419764 : nargs.dp = dp;
1183 1419764 : nargs.total = args->total;
1184 1419764 : nargs.whichfork = XFS_ATTR_FORK;
1185 1419764 : nargs.trans = args->trans;
1186 1419764 : nargs.op_flags = XFS_DA_OP_OKNOENT;
1187 :
1188 7996564 : for (i = 0; i < ichdr.count; entry++, i++) {
1189 6576685 : if (entry->flags & XFS_ATTR_INCOMPLETE)
1190 0 : continue; /* don't copy partial entries */
1191 6576685 : if (!entry->nameidx)
1192 0 : continue;
1193 6576685 : ASSERT(entry->flags & XFS_ATTR_LOCAL);
1194 6576685 : name_loc = xfs_attr3_leaf_name_local(leaf, i);
1195 6576685 : nargs.name = name_loc->nameval;
1196 6576685 : nargs.namelen = name_loc->namelen;
1197 6576685 : nargs.value = &name_loc->nameval[nargs.namelen];
1198 6576685 : nargs.valuelen = be16_to_cpu(name_loc->valuelen);
1199 6576685 : nargs.hashval = be32_to_cpu(entry->hashval);
1200 6576685 : nargs.attr_filter = entry->flags & XFS_ATTR_NSP_ONDISK_MASK;
1201 6576685 : xfs_attr_shortform_add(&nargs, forkoff);
1202 : }
1203 : error = 0;
1204 :
1205 1420217 : out:
1206 1420217 : kmem_free(tmpbuffer);
1207 1420217 : return error;
1208 : }
1209 :
1210 : /*
1211 : * Convert from using a single leaf to a root node and a leaf.
1212 : */
1213 : int
1214 24559 : xfs_attr3_leaf_to_node(
1215 : struct xfs_da_args *args)
1216 : {
1217 24559 : struct xfs_attr_leafblock *leaf;
1218 24559 : struct xfs_attr3_icleaf_hdr icleafhdr;
1219 24559 : struct xfs_attr_leaf_entry *entries;
1220 24559 : struct xfs_da3_icnode_hdr icnodehdr;
1221 24559 : struct xfs_da_intnode *node;
1222 24559 : struct xfs_inode *dp = args->dp;
1223 24559 : struct xfs_mount *mp = dp->i_mount;
1224 24559 : struct xfs_buf *bp1 = NULL;
1225 24559 : struct xfs_buf *bp2 = NULL;
1226 24559 : xfs_dablk_t blkno;
1227 24559 : int error;
1228 :
1229 24559 : trace_xfs_attr_leaf_to_node(args);
1230 :
1231 24559 : if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_ATTR_LEAF_TO_NODE)) {
1232 11 : error = -EIO;
1233 11 : goto out;
1234 : }
1235 :
1236 24548 : error = xfs_da_grow_inode(args, &blkno);
1237 24548 : if (error)
1238 0 : goto out;
1239 24548 : error = xfs_attr3_leaf_read(args->trans, dp, 0, &bp1);
1240 24548 : if (error)
1241 0 : goto out;
1242 :
1243 24548 : error = xfs_da_get_buf(args->trans, dp, blkno, &bp2, XFS_ATTR_FORK);
1244 24548 : if (error)
1245 0 : goto out;
1246 :
1247 : /* copy leaf to new buffer, update identifiers */
1248 24548 : xfs_trans_buf_set_type(args->trans, bp2, XFS_BLFT_ATTR_LEAF_BUF);
1249 24548 : bp2->b_ops = bp1->b_ops;
1250 49096 : memcpy(bp2->b_addr, bp1->b_addr, args->geo->blksize);
1251 24548 : if (xfs_has_crc(mp)) {
1252 24548 : struct xfs_da3_blkinfo *hdr3 = bp2->b_addr;
1253 24548 : hdr3->blkno = cpu_to_be64(xfs_buf_daddr(bp2));
1254 : }
1255 24548 : xfs_trans_log_buf(args->trans, bp2, 0, args->geo->blksize - 1);
1256 :
1257 : /*
1258 : * Set up the new root node.
1259 : */
1260 24548 : error = xfs_da3_node_create(args, 0, 1, &bp1, XFS_ATTR_FORK);
1261 24548 : if (error)
1262 0 : goto out;
1263 24548 : node = bp1->b_addr;
1264 24548 : xfs_da3_node_hdr_from_disk(mp, &icnodehdr, node);
1265 :
1266 24548 : leaf = bp2->b_addr;
1267 24548 : xfs_attr3_leaf_hdr_from_disk(args->geo, &icleafhdr, leaf);
1268 24548 : entries = xfs_attr3_leaf_entryp(leaf);
1269 :
1270 : /* both on-disk, don't endian-flip twice */
1271 24548 : icnodehdr.btree[0].hashval = entries[icleafhdr.count - 1].hashval;
1272 24548 : icnodehdr.btree[0].before = cpu_to_be32(blkno);
1273 24548 : icnodehdr.count = 1;
1274 24548 : xfs_da3_node_hdr_to_disk(dp->i_mount, node, &icnodehdr);
1275 24548 : xfs_trans_log_buf(args->trans, bp1, 0, args->geo->blksize - 1);
1276 24548 : error = 0;
1277 24559 : out:
1278 24559 : return error;
1279 : }
1280 :
1281 : /*========================================================================
1282 : * Routines used for growing the Btree.
1283 : *========================================================================*/
1284 :
1285 : /*
1286 : * Create the initial contents of a leaf attribute list
1287 : * or a leaf in a node attribute list.
1288 : */
1289 : STATIC int
1290 2932037 : xfs_attr3_leaf_create(
1291 : struct xfs_da_args *args,
1292 : xfs_dablk_t blkno,
1293 : struct xfs_buf **bpp)
1294 : {
1295 2932037 : struct xfs_attr_leafblock *leaf;
1296 2932037 : struct xfs_attr3_icleaf_hdr ichdr;
1297 2932037 : struct xfs_inode *dp = args->dp;
1298 2932037 : struct xfs_mount *mp = dp->i_mount;
1299 2932037 : struct xfs_buf *bp;
1300 2932037 : int error;
1301 :
1302 2932037 : trace_xfs_attr_leaf_create(args);
1303 :
1304 2930094 : error = xfs_da_get_buf(args->trans, args->dp, blkno, &bp,
1305 : XFS_ATTR_FORK);
1306 2932063 : if (error)
1307 : return error;
1308 2931432 : bp->b_ops = &xfs_attr3_leaf_buf_ops;
1309 2931432 : xfs_trans_buf_set_type(args->trans, bp, XFS_BLFT_ATTR_LEAF_BUF);
1310 2932722 : leaf = bp->b_addr;
1311 2932722 : memset(leaf, 0, args->geo->blksize);
1312 :
1313 2932722 : memset(&ichdr, 0, sizeof(ichdr));
1314 2932722 : ichdr.firstused = args->geo->blksize;
1315 :
1316 2932722 : if (xfs_has_crc(mp)) {
1317 2932722 : struct xfs_da3_blkinfo *hdr3 = bp->b_addr;
1318 :
1319 2932722 : ichdr.magic = XFS_ATTR3_LEAF_MAGIC;
1320 :
1321 2932722 : hdr3->blkno = cpu_to_be64(xfs_buf_daddr(bp));
1322 2932722 : hdr3->owner = cpu_to_be64(dp->i_ino);
1323 2932722 : uuid_copy(&hdr3->uuid, &mp->m_sb.sb_meta_uuid);
1324 :
1325 2929280 : ichdr.freemap[0].base = sizeof(struct xfs_attr3_leaf_hdr);
1326 : } else {
1327 0 : ichdr.magic = XFS_ATTR_LEAF_MAGIC;
1328 0 : ichdr.freemap[0].base = sizeof(struct xfs_attr_leaf_hdr);
1329 : }
1330 2929280 : ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base;
1331 :
1332 2929280 : xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr);
1333 2928902 : xfs_trans_log_buf(args->trans, bp, 0, args->geo->blksize - 1);
1334 :
1335 2928413 : *bpp = bp;
1336 2928413 : return 0;
1337 : }
1338 :
1339 : /*
1340 : * Split the leaf node, rebalance, then add the new entry.
1341 : */
1342 : int
1343 88853 : xfs_attr3_leaf_split(
1344 : struct xfs_da_state *state,
1345 : struct xfs_da_state_blk *oldblk,
1346 : struct xfs_da_state_blk *newblk)
1347 : {
1348 88853 : xfs_dablk_t blkno;
1349 88853 : int error;
1350 :
1351 88853 : trace_xfs_attr_leaf_split(state->args);
1352 :
1353 : /*
1354 : * Allocate space for a new leaf node.
1355 : */
1356 88853 : ASSERT(oldblk->magic == XFS_ATTR_LEAF_MAGIC);
1357 88853 : error = xfs_da_grow_inode(state->args, &blkno);
1358 88853 : if (error)
1359 : return error;
1360 88853 : error = xfs_attr3_leaf_create(state->args, blkno, &newblk->bp);
1361 88853 : if (error)
1362 : return error;
1363 88853 : newblk->blkno = blkno;
1364 88853 : newblk->magic = XFS_ATTR_LEAF_MAGIC;
1365 :
1366 : /*
1367 : * Rebalance the entries across the two leaves.
1368 : * NOTE: rebalance() currently depends on the 2nd block being empty.
1369 : */
1370 88853 : xfs_attr3_leaf_rebalance(state, oldblk, newblk);
1371 88853 : error = xfs_da3_blk_link(state, oldblk, newblk);
1372 88853 : if (error)
1373 : return error;
1374 :
1375 : /*
1376 : * Save info on "old" attribute for "atomic rename" ops, leaf_add()
1377 : * modifies the index/blkno/rmtblk/rmtblkcnt fields to show the
1378 : * "new" attrs info. Will need the "old" info to remove it later.
1379 : *
1380 : * Insert the "new" entry in the correct block.
1381 : */
1382 88853 : if (state->inleaf) {
1383 8156 : trace_xfs_attr_leaf_add_old(state->args);
1384 8156 : error = xfs_attr3_leaf_add(oldblk->bp, state->args);
1385 : } else {
1386 80697 : trace_xfs_attr_leaf_add_new(state->args);
1387 80697 : error = xfs_attr3_leaf_add(newblk->bp, state->args);
1388 : }
1389 :
1390 : /*
1391 : * Update last hashval in each block since we added the name.
1392 : */
1393 88853 : oldblk->hashval = xfs_attr_leaf_lasthash(oldblk->bp, NULL);
1394 88853 : newblk->hashval = xfs_attr_leaf_lasthash(newblk->bp, NULL);
1395 88853 : return error;
1396 : }
1397 :
1398 : /*
1399 : * Add a name to the leaf attribute list structure.
1400 : */
1401 : int
1402 60926707 : xfs_attr3_leaf_add(
1403 : struct xfs_buf *bp,
1404 : struct xfs_da_args *args)
1405 : {
1406 60926707 : struct xfs_attr_leafblock *leaf;
1407 60926707 : struct xfs_attr3_icleaf_hdr ichdr;
1408 60926707 : int tablesize;
1409 60926707 : int entsize;
1410 60926707 : int sum;
1411 60926707 : int tmp;
1412 60926707 : int i;
1413 :
1414 60926707 : trace_xfs_attr_leaf_add(args);
1415 :
1416 60873132 : leaf = bp->b_addr;
1417 60873132 : xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
1418 60855265 : ASSERT(args->index >= 0 && args->index <= ichdr.count);
1419 60855265 : entsize = xfs_attr_leaf_newentsize(args, NULL);
1420 :
1421 : /*
1422 : * Search through freemap for first-fit on new name length.
1423 : * (may need to figure in size of entry struct too)
1424 : */
1425 60856391 : tablesize = (ichdr.count + 1) * sizeof(xfs_attr_leaf_entry_t)
1426 60856391 : + xfs_attr3_leaf_hdr_size(leaf);
1427 147935636 : for (sum = 0, i = XFS_ATTR_LEAF_MAPSIZE - 1; i >= 0; i--) {
1428 147647699 : if (tablesize > ichdr.firstused) {
1429 57705 : sum += ichdr.freemap[i].size;
1430 57705 : continue;
1431 : }
1432 147589994 : if (!ichdr.freemap[i].size)
1433 47635213 : continue; /* no space in this map */
1434 99924262 : tmp = entsize;
1435 99924262 : if (ichdr.freemap[i].base < ichdr.firstused)
1436 39169164 : tmp += sizeof(xfs_attr_leaf_entry_t);
1437 99928106 : if (ichdr.freemap[i].size >= tmp) {
1438 60605004 : tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, i);
1439 60613905 : goto out_log_hdr;
1440 : }
1441 39385728 : sum += ichdr.freemap[i].size;
1442 : }
1443 :
1444 : /*
1445 : * If there are no holes in the address space of the block,
1446 : * and we don't have enough freespace, then compaction will do us
1447 : * no good and we should just give up.
1448 : */
1449 287937 : if (!ichdr.holes && sum < entsize)
1450 : return -ENOSPC;
1451 :
1452 : /*
1453 : * Compact the entries to coalesce free space.
1454 : * This may change the hdr->count via dropping INCOMPLETE entries.
1455 : */
1456 192131 : xfs_attr3_leaf_compact(args, &ichdr, bp);
1457 :
1458 : /*
1459 : * After compaction, the block is guaranteed to have only one
1460 : * free region, in freemap[0]. If it is not big enough, give up.
1461 : */
1462 192132 : if (ichdr.freemap[0].size < (entsize + sizeof(xfs_attr_leaf_entry_t))) {
1463 17617 : tmp = -ENOSPC;
1464 17617 : goto out_log_hdr;
1465 : }
1466 :
1467 174515 : tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, 0);
1468 :
1469 60806036 : out_log_hdr:
1470 60806036 : xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr);
1471 60656704 : xfs_trans_log_buf(args->trans, bp,
1472 60656704 : XFS_DA_LOGRANGE(leaf, &leaf->hdr,
1473 : xfs_attr3_leaf_hdr_size(leaf)));
1474 60656704 : return tmp;
1475 : }
1476 :
1477 : /*
1478 : * Add a name to a leaf attribute list structure.
1479 : */
1480 : STATIC int
1481 60784889 : xfs_attr3_leaf_add_work(
1482 : struct xfs_buf *bp,
1483 : struct xfs_attr3_icleaf_hdr *ichdr,
1484 : struct xfs_da_args *args,
1485 : int mapindex)
1486 : {
1487 60784889 : struct xfs_attr_leafblock *leaf;
1488 60784889 : struct xfs_attr_leaf_entry *entry;
1489 60784889 : struct xfs_attr_leaf_name_local *name_loc;
1490 60784889 : struct xfs_attr_leaf_name_remote *name_rmt;
1491 60784889 : struct xfs_mount *mp;
1492 60784889 : int tmp;
1493 60784889 : int i;
1494 :
1495 60784889 : trace_xfs_attr_leaf_add_work(args);
1496 :
1497 60754008 : leaf = bp->b_addr;
1498 60754008 : ASSERT(mapindex >= 0 && mapindex < XFS_ATTR_LEAF_MAPSIZE);
1499 60754008 : ASSERT(args->index >= 0 && args->index <= ichdr->count);
1500 :
1501 : /*
1502 : * Force open some space in the entry array and fill it in.
1503 : */
1504 60754008 : entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
1505 60754008 : if (args->index < ichdr->count) {
1506 21225228 : tmp = ichdr->count - args->index;
1507 21225228 : tmp *= sizeof(xfs_attr_leaf_entry_t);
1508 42450456 : memmove(entry + 1, entry, tmp);
1509 21225228 : xfs_trans_log_buf(args->trans, bp,
1510 21225228 : XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry)));
1511 : }
1512 60763387 : ichdr->count++;
1513 :
1514 : /*
1515 : * Allocate space for the new string (at the end of the run).
1516 : */
1517 60763387 : mp = args->trans->t_mountp;
1518 60763387 : ASSERT(ichdr->freemap[mapindex].base < args->geo->blksize);
1519 60805662 : ASSERT((ichdr->freemap[mapindex].base & 0x3) == 0);
1520 60802128 : ASSERT(ichdr->freemap[mapindex].size >=
1521 : xfs_attr_leaf_newentsize(args, NULL));
1522 60771609 : ASSERT(ichdr->freemap[mapindex].size < args->geo->blksize);
1523 60773887 : ASSERT((ichdr->freemap[mapindex].size & 0x3) == 0);
1524 :
1525 60775821 : ichdr->freemap[mapindex].size -= xfs_attr_leaf_newentsize(args, &tmp);
1526 :
1527 60790507 : entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base +
1528 : ichdr->freemap[mapindex].size);
1529 60789883 : entry->hashval = cpu_to_be32(args->hashval);
1530 60789883 : entry->flags = args->attr_filter;
1531 60789883 : if (tmp)
1532 60789363 : entry->flags |= XFS_ATTR_LOCAL;
1533 60789883 : if (args->op_flags & XFS_DA_OP_REPLACE) {
1534 11242064 : if (!(args->op_flags & XFS_DA_OP_LOGGED))
1535 11242019 : entry->flags |= XFS_ATTR_INCOMPLETE;
1536 11242064 : if ((args->blkno2 == args->blkno) &&
1537 11241146 : (args->index2 <= args->index)) {
1538 11241039 : args->index2++;
1539 : }
1540 : }
1541 60789883 : xfs_trans_log_buf(args->trans, bp,
1542 60789883 : XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
1543 60783926 : ASSERT((args->index == 0) ||
1544 : (be32_to_cpu(entry->hashval) >= be32_to_cpu((entry-1)->hashval)));
1545 60783926 : ASSERT((args->index == ichdr->count - 1) ||
1546 : (be32_to_cpu(entry->hashval) <= be32_to_cpu((entry+1)->hashval)));
1547 :
1548 : /*
1549 : * For "remote" attribute values, simply note that we need to
1550 : * allocate space for the "remote" value. We can't actually
1551 : * allocate the extents in this transaction, and we can't decide
1552 : * which blocks they should be as we might allocate more blocks
1553 : * as part of this transaction (a split operation for example).
1554 : */
1555 60783926 : if (entry->flags & XFS_ATTR_LOCAL) {
1556 60781090 : name_loc = xfs_attr3_leaf_name_local(leaf, args->index);
1557 60781090 : name_loc->namelen = args->namelen;
1558 60781090 : name_loc->valuelen = cpu_to_be16(args->valuelen);
1559 121562180 : memcpy((char *)name_loc->nameval, args->name, args->namelen);
1560 121562180 : memcpy((char *)&name_loc->nameval[args->namelen], args->value,
1561 : be16_to_cpu(name_loc->valuelen));
1562 : } else {
1563 2836 : name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
1564 2836 : name_rmt->namelen = args->namelen;
1565 5672 : memcpy((char *)name_rmt->name, args->name, args->namelen);
1566 2836 : entry->flags |= XFS_ATTR_INCOMPLETE;
1567 : /* just in case */
1568 2836 : name_rmt->valuelen = 0;
1569 2836 : name_rmt->valueblk = 0;
1570 2836 : args->rmtblkno = 1;
1571 2836 : args->rmtblkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen);
1572 2836 : args->rmtvaluelen = args->valuelen;
1573 : }
1574 121567852 : xfs_trans_log_buf(args->trans, bp,
1575 121567852 : XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index),
1576 : xfs_attr_leaf_entsize(leaf, args->index)));
1577 :
1578 : /*
1579 : * Update the control info for this leaf node
1580 : */
1581 60839931 : if (be16_to_cpu(entry->nameidx) < ichdr->firstused)
1582 39096239 : ichdr->firstused = be16_to_cpu(entry->nameidx);
1583 :
1584 121676623 : ASSERT(ichdr->firstused >= ichdr->count * sizeof(xfs_attr_leaf_entry_t)
1585 : + xfs_attr3_leaf_hdr_size(leaf));
1586 121679862 : tmp = (ichdr->count - 1) * sizeof(xfs_attr_leaf_entry_t)
1587 60839931 : + xfs_attr3_leaf_hdr_size(leaf);
1588 :
1589 242905783 : for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
1590 182140827 : if (ichdr->freemap[i].base == tmp) {
1591 60750671 : ichdr->freemap[i].base += sizeof(xfs_attr_leaf_entry_t);
1592 60742913 : ichdr->freemap[i].size -=
1593 60763039 : min_t(uint16_t, ichdr->freemap[i].size,
1594 : sizeof(xfs_attr_leaf_entry_t));
1595 : }
1596 : }
1597 60764956 : ichdr->usedbytes += xfs_attr_leaf_entsize(leaf, args->index);
1598 60764956 : return 0;
1599 : }
1600 :
1601 : /*
1602 : * Garbage collect a leaf attribute list block by copying it to a new buffer.
1603 : */
1604 : STATIC void
1605 192129 : xfs_attr3_leaf_compact(
1606 : struct xfs_da_args *args,
1607 : struct xfs_attr3_icleaf_hdr *ichdr_dst,
1608 : struct xfs_buf *bp)
1609 : {
1610 192129 : struct xfs_attr_leafblock *leaf_src;
1611 192129 : struct xfs_attr_leafblock *leaf_dst;
1612 192129 : struct xfs_attr3_icleaf_hdr ichdr_src;
1613 192129 : struct xfs_trans *trans = args->trans;
1614 192129 : char *tmpbuffer;
1615 :
1616 192129 : trace_xfs_attr_leaf_compact(args);
1617 :
1618 192129 : tmpbuffer = kmem_alloc(args->geo->blksize, 0);
1619 384262 : memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
1620 192131 : memset(bp->b_addr, 0, args->geo->blksize);
1621 192131 : leaf_src = (xfs_attr_leafblock_t *)tmpbuffer;
1622 192131 : leaf_dst = bp->b_addr;
1623 :
1624 : /*
1625 : * Copy the on-disk header back into the destination buffer to ensure
1626 : * all the information in the header that is not part of the incore
1627 : * header structure is preserved.
1628 : */
1629 576394 : memcpy(bp->b_addr, tmpbuffer, xfs_attr3_leaf_hdr_size(leaf_src));
1630 :
1631 : /* Initialise the incore headers */
1632 192131 : ichdr_src = *ichdr_dst; /* struct copy */
1633 192131 : ichdr_dst->firstused = args->geo->blksize;
1634 192131 : ichdr_dst->usedbytes = 0;
1635 192131 : ichdr_dst->count = 0;
1636 192131 : ichdr_dst->holes = 0;
1637 192131 : ichdr_dst->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_src);
1638 192131 : ichdr_dst->freemap[0].size = ichdr_dst->firstused -
1639 : ichdr_dst->freemap[0].base;
1640 :
1641 : /* write the header back to initialise the underlying buffer */
1642 192131 : xfs_attr3_leaf_hdr_to_disk(args->geo, leaf_dst, ichdr_dst);
1643 :
1644 : /*
1645 : * Copy all entry's in the same (sorted) order,
1646 : * but allocate name/value pairs packed and in sequence.
1647 : */
1648 192131 : xfs_attr3_leaf_moveents(args, leaf_src, &ichdr_src, 0,
1649 192131 : leaf_dst, ichdr_dst, 0, ichdr_src.count);
1650 : /*
1651 : * this logs the entire buffer, but the caller must write the header
1652 : * back to the buffer when it is finished modifying it.
1653 : */
1654 192131 : xfs_trans_log_buf(trans, bp, 0, args->geo->blksize - 1);
1655 :
1656 192131 : kmem_free(tmpbuffer);
1657 192131 : }
1658 :
1659 : /*
1660 : * Compare two leaf blocks "order".
1661 : * Return 0 unless leaf2 should go before leaf1.
1662 : */
1663 : static int
1664 178306 : xfs_attr3_leaf_order(
1665 : struct xfs_buf *leaf1_bp,
1666 : struct xfs_attr3_icleaf_hdr *leaf1hdr,
1667 : struct xfs_buf *leaf2_bp,
1668 : struct xfs_attr3_icleaf_hdr *leaf2hdr)
1669 : {
1670 178306 : struct xfs_attr_leaf_entry *entries1;
1671 178306 : struct xfs_attr_leaf_entry *entries2;
1672 :
1673 178306 : entries1 = xfs_attr3_leaf_entryp(leaf1_bp->b_addr);
1674 178306 : entries2 = xfs_attr3_leaf_entryp(leaf2_bp->b_addr);
1675 178306 : if (leaf1hdr->count > 0 && leaf2hdr->count > 0 &&
1676 89453 : ((be32_to_cpu(entries2[0].hashval) <
1677 89453 : be32_to_cpu(entries1[0].hashval)) ||
1678 89240 : (be32_to_cpu(entries2[leaf2hdr->count - 1].hashval) <
1679 89240 : be32_to_cpu(entries1[leaf1hdr->count - 1].hashval)))) {
1680 213 : return 1;
1681 : }
1682 : return 0;
1683 : }
1684 :
1685 : int
1686 88853 : xfs_attr_leaf_order(
1687 : struct xfs_buf *leaf1_bp,
1688 : struct xfs_buf *leaf2_bp)
1689 : {
1690 88853 : struct xfs_attr3_icleaf_hdr ichdr1;
1691 88853 : struct xfs_attr3_icleaf_hdr ichdr2;
1692 88853 : struct xfs_mount *mp = leaf1_bp->b_mount;
1693 :
1694 88853 : xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr1, leaf1_bp->b_addr);
1695 88853 : xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr2, leaf2_bp->b_addr);
1696 88853 : return xfs_attr3_leaf_order(leaf1_bp, &ichdr1, leaf2_bp, &ichdr2);
1697 : }
1698 :
1699 : /*
1700 : * Redistribute the attribute list entries between two leaf nodes,
1701 : * taking into account the size of the new entry.
1702 : *
1703 : * NOTE: if new block is empty, then it will get the upper half of the
1704 : * old block. At present, all (one) callers pass in an empty second block.
1705 : *
1706 : * This code adjusts the args->index/blkno and args->index2/blkno2 fields
1707 : * to match what it is doing in splitting the attribute leaf block. Those
1708 : * values are used in "atomic rename" operations on attributes. Note that
1709 : * the "new" and "old" values can end up in different blocks.
1710 : */
1711 : STATIC void
1712 88853 : xfs_attr3_leaf_rebalance(
1713 : struct xfs_da_state *state,
1714 : struct xfs_da_state_blk *blk1,
1715 : struct xfs_da_state_blk *blk2)
1716 : {
1717 88853 : struct xfs_da_args *args;
1718 88853 : struct xfs_attr_leafblock *leaf1;
1719 88853 : struct xfs_attr_leafblock *leaf2;
1720 88853 : struct xfs_attr3_icleaf_hdr ichdr1;
1721 88853 : struct xfs_attr3_icleaf_hdr ichdr2;
1722 88853 : struct xfs_attr_leaf_entry *entries1;
1723 88853 : struct xfs_attr_leaf_entry *entries2;
1724 88853 : int count;
1725 88853 : int totallen;
1726 88853 : int max;
1727 88853 : int space;
1728 88853 : int swap;
1729 :
1730 : /*
1731 : * Set up environment.
1732 : */
1733 88853 : ASSERT(blk1->magic == XFS_ATTR_LEAF_MAGIC);
1734 88853 : ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC);
1735 88853 : leaf1 = blk1->bp->b_addr;
1736 88853 : leaf2 = blk2->bp->b_addr;
1737 88853 : xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr1, leaf1);
1738 88853 : xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr2, leaf2);
1739 88853 : ASSERT(ichdr2.count == 0);
1740 88853 : args = state->args;
1741 :
1742 88853 : trace_xfs_attr_leaf_rebalance(args);
1743 :
1744 : /*
1745 : * Check ordering of blocks, reverse if it makes things simpler.
1746 : *
1747 : * NOTE: Given that all (current) callers pass in an empty
1748 : * second block, this code should never set "swap".
1749 : */
1750 88853 : swap = 0;
1751 88853 : if (xfs_attr3_leaf_order(blk1->bp, &ichdr1, blk2->bp, &ichdr2)) {
1752 0 : swap(blk1, blk2);
1753 :
1754 : /* swap structures rather than reconverting them */
1755 0 : swap(ichdr1, ichdr2);
1756 :
1757 0 : leaf1 = blk1->bp->b_addr;
1758 0 : leaf2 = blk2->bp->b_addr;
1759 0 : swap = 1;
1760 : }
1761 :
1762 : /*
1763 : * Examine entries until we reduce the absolute difference in
1764 : * byte usage between the two blocks to a minimum. Then get
1765 : * the direction to copy and the number of elements to move.
1766 : *
1767 : * "inleaf" is true if the new entry should be inserted into blk1.
1768 : * If "swap" is also true, then reverse the sense of "inleaf".
1769 : */
1770 88853 : state->inleaf = xfs_attr3_leaf_figure_balance(state, blk1, &ichdr1,
1771 : blk2, &ichdr2,
1772 : &count, &totallen);
1773 88853 : if (swap)
1774 0 : state->inleaf = !state->inleaf;
1775 :
1776 : /*
1777 : * Move any entries required from leaf to leaf:
1778 : */
1779 88853 : if (count < ichdr1.count) {
1780 : /*
1781 : * Figure the total bytes to be added to the destination leaf.
1782 : */
1783 : /* number entries being moved */
1784 88853 : count = ichdr1.count - count;
1785 88853 : space = ichdr1.usedbytes - totallen;
1786 88853 : space += count * sizeof(xfs_attr_leaf_entry_t);
1787 :
1788 : /*
1789 : * leaf2 is the destination, compact it if it looks tight.
1790 : */
1791 88853 : max = ichdr2.firstused - xfs_attr3_leaf_hdr_size(leaf1);
1792 88853 : max -= ichdr2.count * sizeof(xfs_attr_leaf_entry_t);
1793 88853 : if (space > max)
1794 0 : xfs_attr3_leaf_compact(args, &ichdr2, blk2->bp);
1795 :
1796 : /*
1797 : * Move high entries from leaf1 to low end of leaf2.
1798 : */
1799 88853 : xfs_attr3_leaf_moveents(args, leaf1, &ichdr1,
1800 88853 : ichdr1.count - count, leaf2, &ichdr2, 0, count);
1801 :
1802 0 : } else if (count > ichdr1.count) {
1803 : /*
1804 : * I assert that since all callers pass in an empty
1805 : * second buffer, this code should never execute.
1806 : */
1807 0 : ASSERT(0);
1808 :
1809 : /*
1810 : * Figure the total bytes to be added to the destination leaf.
1811 : */
1812 : /* number entries being moved */
1813 0 : count -= ichdr1.count;
1814 0 : space = totallen - ichdr1.usedbytes;
1815 0 : space += count * sizeof(xfs_attr_leaf_entry_t);
1816 :
1817 : /*
1818 : * leaf1 is the destination, compact it if it looks tight.
1819 : */
1820 0 : max = ichdr1.firstused - xfs_attr3_leaf_hdr_size(leaf1);
1821 0 : max -= ichdr1.count * sizeof(xfs_attr_leaf_entry_t);
1822 0 : if (space > max)
1823 0 : xfs_attr3_leaf_compact(args, &ichdr1, blk1->bp);
1824 :
1825 : /*
1826 : * Move low entries from leaf2 to high end of leaf1.
1827 : */
1828 0 : xfs_attr3_leaf_moveents(args, leaf2, &ichdr2, 0, leaf1, &ichdr1,
1829 0 : ichdr1.count, count);
1830 : }
1831 :
1832 88853 : xfs_attr3_leaf_hdr_to_disk(state->args->geo, leaf1, &ichdr1);
1833 88853 : xfs_attr3_leaf_hdr_to_disk(state->args->geo, leaf2, &ichdr2);
1834 88853 : xfs_trans_log_buf(args->trans, blk1->bp, 0, args->geo->blksize - 1);
1835 88853 : xfs_trans_log_buf(args->trans, blk2->bp, 0, args->geo->blksize - 1);
1836 :
1837 : /*
1838 : * Copy out last hashval in each block for B-tree code.
1839 : */
1840 88853 : entries1 = xfs_attr3_leaf_entryp(leaf1);
1841 88853 : entries2 = xfs_attr3_leaf_entryp(leaf2);
1842 88853 : blk1->hashval = be32_to_cpu(entries1[ichdr1.count - 1].hashval);
1843 88853 : blk2->hashval = be32_to_cpu(entries2[ichdr2.count - 1].hashval);
1844 :
1845 : /*
1846 : * Adjust the expected index for insertion.
1847 : * NOTE: this code depends on the (current) situation that the
1848 : * second block was originally empty.
1849 : *
1850 : * If the insertion point moved to the 2nd block, we must adjust
1851 : * the index. We must also track the entry just following the
1852 : * new entry for use in an "atomic rename" operation, that entry
1853 : * is always the "old" entry and the "new" entry is what we are
1854 : * inserting. The index/blkno fields refer to the "old" entry,
1855 : * while the index2/blkno2 fields refer to the "new" entry.
1856 : */
1857 88853 : if (blk1->index > ichdr1.count) {
1858 80415 : ASSERT(state->inleaf == 0);
1859 80415 : blk2->index = blk1->index - ichdr1.count;
1860 80415 : args->index = args->index2 = blk2->index;
1861 80415 : args->blkno = args->blkno2 = blk2->blkno;
1862 8438 : } else if (blk1->index == ichdr1.count) {
1863 490 : if (state->inleaf) {
1864 208 : args->index = blk1->index;
1865 208 : args->blkno = blk1->blkno;
1866 208 : args->index2 = 0;
1867 208 : args->blkno2 = blk2->blkno;
1868 : } else {
1869 : /*
1870 : * On a double leaf split, the original attr location
1871 : * is already stored in blkno2/index2, so don't
1872 : * overwrite it overwise we corrupt the tree.
1873 : */
1874 282 : blk2->index = blk1->index - ichdr1.count;
1875 282 : args->index = blk2->index;
1876 282 : args->blkno = blk2->blkno;
1877 282 : if (!state->extravalid) {
1878 : /*
1879 : * set the new attr location to match the old
1880 : * one and let the higher level split code
1881 : * decide where in the leaf to place it.
1882 : */
1883 282 : args->index2 = blk2->index;
1884 282 : args->blkno2 = blk2->blkno;
1885 : }
1886 : }
1887 : } else {
1888 7948 : ASSERT(state->inleaf == 1);
1889 7948 : args->index = args->index2 = blk1->index;
1890 7948 : args->blkno = args->blkno2 = blk1->blkno;
1891 : }
1892 88853 : }
1893 :
1894 : /*
1895 : * Examine entries until we reduce the absolute difference in
1896 : * byte usage between the two blocks to a minimum.
1897 : * GROT: Is this really necessary? With other than a 512 byte blocksize,
1898 : * GROT: there will always be enough room in either block for a new entry.
1899 : * GROT: Do a double-split for this case?
1900 : */
1901 : STATIC int
1902 88853 : xfs_attr3_leaf_figure_balance(
1903 : struct xfs_da_state *state,
1904 : struct xfs_da_state_blk *blk1,
1905 : struct xfs_attr3_icleaf_hdr *ichdr1,
1906 : struct xfs_da_state_blk *blk2,
1907 : struct xfs_attr3_icleaf_hdr *ichdr2,
1908 : int *countarg,
1909 : int *usedbytesarg)
1910 : {
1911 88853 : struct xfs_attr_leafblock *leaf1 = blk1->bp->b_addr;
1912 88853 : struct xfs_attr_leafblock *leaf2 = blk2->bp->b_addr;
1913 88853 : struct xfs_attr_leaf_entry *entry;
1914 88853 : int count;
1915 88853 : int max;
1916 88853 : int index;
1917 88853 : int totallen = 0;
1918 88853 : int half;
1919 88853 : int lastdelta;
1920 88853 : int foundit = 0;
1921 88853 : int tmp;
1922 :
1923 : /*
1924 : * Examine entries until we reduce the absolute difference in
1925 : * byte usage between the two blocks to a minimum.
1926 : */
1927 88853 : max = ichdr1->count + ichdr2->count;
1928 88853 : half = (max + 1) * sizeof(*entry);
1929 177706 : half += ichdr1->usedbytes + ichdr2->usedbytes +
1930 88853 : xfs_attr_leaf_newentsize(state->args, NULL);
1931 88853 : half /= 2;
1932 88853 : lastdelta = state->args->geo->blksize;
1933 88853 : entry = xfs_attr3_leaf_entryp(leaf1);
1934 1307716 : for (count = index = 0; count < max; entry++, index++, count++) {
1935 :
1936 : #define XFS_ATTR_ABS(A) (((A) < 0) ? -(A) : (A))
1937 : /*
1938 : * The new entry is in the first block, account for it.
1939 : */
1940 1307716 : if (count == blk1->index) {
1941 16876 : tmp = totallen + sizeof(*entry) +
1942 8438 : xfs_attr_leaf_newentsize(state->args, NULL);
1943 8438 : if (XFS_ATTR_ABS(half - tmp) > lastdelta)
1944 : break;
1945 : lastdelta = XFS_ATTR_ABS(half - tmp);
1946 : totallen = tmp;
1947 : foundit = 1;
1948 : }
1949 :
1950 : /*
1951 : * Wrap around into the second block if necessary.
1952 : */
1953 1307434 : if (count == ichdr1->count) {
1954 0 : leaf1 = leaf2;
1955 0 : entry = xfs_attr3_leaf_entryp(leaf1);
1956 : index = 0;
1957 : }
1958 :
1959 : /*
1960 : * Figure out if next leaf entry would be too much.
1961 : */
1962 1307434 : tmp = totallen + sizeof(*entry) + xfs_attr_leaf_entsize(leaf1,
1963 : index);
1964 1307434 : if (XFS_ATTR_ABS(half - tmp) > lastdelta)
1965 : break;
1966 1218863 : lastdelta = XFS_ATTR_ABS(half - tmp);
1967 1218863 : totallen = tmp;
1968 : #undef XFS_ATTR_ABS
1969 : }
1970 :
1971 : /*
1972 : * Calculate the number of usedbytes that will end up in lower block.
1973 : * If new entry not in lower block, fix up the count.
1974 : */
1975 88853 : totallen -= count * sizeof(*entry);
1976 88853 : if (foundit) {
1977 16312 : totallen -= sizeof(*entry) +
1978 8156 : xfs_attr_leaf_newentsize(state->args, NULL);
1979 : }
1980 :
1981 88853 : *countarg = count;
1982 88853 : *usedbytesarg = totallen;
1983 88853 : return foundit;
1984 : }
1985 :
1986 : /*========================================================================
1987 : * Routines used for shrinking the Btree.
1988 : *========================================================================*/
1989 :
1990 : /*
1991 : * Check a leaf block and its neighbors to see if the block should be
1992 : * collapsed into one or the other neighbor. Always keep the block
1993 : * with the smaller block number.
1994 : * If the current block is over 50% full, don't try to join it, return 0.
1995 : * If the block is empty, fill in the state structure and return 2.
1996 : * If it can be collapsed, fill in the state structure and return 1.
1997 : * If nothing can be done, return 0.
1998 : *
1999 : * GROT: allow for INCOMPLETE entries in calculation.
2000 : */
2001 : int
2002 603771 : xfs_attr3_leaf_toosmall(
2003 : struct xfs_da_state *state,
2004 : int *action)
2005 : {
2006 603771 : struct xfs_attr_leafblock *leaf;
2007 603771 : struct xfs_da_state_blk *blk;
2008 603771 : struct xfs_attr3_icleaf_hdr ichdr;
2009 603771 : struct xfs_buf *bp;
2010 603771 : xfs_dablk_t blkno;
2011 603771 : int bytes;
2012 603771 : int forward;
2013 603771 : int error;
2014 603771 : int retval;
2015 603771 : int i;
2016 :
2017 603771 : trace_xfs_attr_leaf_toosmall(state->args);
2018 :
2019 : /*
2020 : * Check for the degenerate case of the block being over 50% full.
2021 : * If so, it's not worth even looking to see if we might be able
2022 : * to coalesce with a sibling.
2023 : */
2024 603739 : blk = &state->path.blk[ state->path.active-1 ];
2025 603739 : leaf = blk->bp->b_addr;
2026 603739 : xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr, leaf);
2027 603777 : bytes = xfs_attr3_leaf_hdr_size(leaf) +
2028 603777 : ichdr.count * sizeof(xfs_attr_leaf_entry_t) +
2029 603777 : ichdr.usedbytes;
2030 603777 : if (bytes > (state->args->geo->blksize >> 1)) {
2031 400484 : *action = 0; /* blk over 50%, don't try to join */
2032 400484 : return 0;
2033 : }
2034 :
2035 : /*
2036 : * Check for the degenerate case of the block being empty.
2037 : * If the block is empty, we'll simply delete it, no need to
2038 : * coalesce it with a sibling block. We choose (arbitrarily)
2039 : * to merge with the forward block unless it is NULL.
2040 : */
2041 203293 : if (ichdr.count == 0) {
2042 : /*
2043 : * Make altpath point to the block we want to keep and
2044 : * path point to the block we want to drop (this one).
2045 : */
2046 0 : forward = (ichdr.forw != 0);
2047 0 : memcpy(&state->altpath, &state->path, sizeof(state->path));
2048 0 : error = xfs_da3_path_shift(state, &state->altpath, forward,
2049 : 0, &retval);
2050 0 : if (error)
2051 : return error;
2052 0 : if (retval) {
2053 0 : *action = 0;
2054 : } else {
2055 0 : *action = 2;
2056 : }
2057 0 : return 0;
2058 : }
2059 :
2060 : /*
2061 : * Examine each sibling block to see if we can coalesce with
2062 : * at least 25% free space to spare. We need to figure out
2063 : * whether to merge with the forward or the backward block.
2064 : * We prefer coalescing with the lower numbered sibling so as
2065 : * to shrink an attribute list over time.
2066 : */
2067 : /* start with smaller blk num */
2068 203293 : forward = ichdr.forw < ichdr.back;
2069 608931 : for (i = 0; i < 2; forward = !forward, i++) {
2070 406241 : struct xfs_attr3_icleaf_hdr ichdr2;
2071 406241 : if (forward)
2072 : blkno = ichdr.forw;
2073 : else
2074 203197 : blkno = ichdr.back;
2075 406241 : if (blkno == 0)
2076 182480 : continue;
2077 223761 : error = xfs_attr3_leaf_read(state->args->trans, state->args->dp,
2078 : blkno, &bp);
2079 223769 : if (error)
2080 10 : return error;
2081 :
2082 223759 : xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr2, bp->b_addr);
2083 :
2084 447518 : bytes = state->args->geo->blksize -
2085 223759 : (state->args->geo->blksize >> 2) -
2086 223759 : ichdr.usedbytes - ichdr2.usedbytes -
2087 223759 : ((ichdr.count + ichdr2.count) *
2088 223759 : sizeof(xfs_attr_leaf_entry_t)) -
2089 223759 : xfs_attr3_leaf_hdr_size(leaf);
2090 :
2091 223759 : xfs_trans_brelse(state->args->trans, bp);
2092 223758 : if (bytes >= 0)
2093 : break; /* fits with at least 25% to spare */
2094 : }
2095 203290 : if (i >= 2) {
2096 202690 : *action = 0;
2097 202690 : return 0;
2098 : }
2099 :
2100 : /*
2101 : * Make altpath point to the block we want to keep (the lower
2102 : * numbered block) and path point to the block we want to drop.
2103 : */
2104 1200 : memcpy(&state->altpath, &state->path, sizeof(state->path));
2105 600 : if (blkno < blk->blkno) {
2106 331 : error = xfs_da3_path_shift(state, &state->altpath, forward,
2107 : 0, &retval);
2108 : } else {
2109 269 : error = xfs_da3_path_shift(state, &state->path, forward,
2110 : 0, &retval);
2111 : }
2112 600 : if (error)
2113 : return error;
2114 600 : if (retval) {
2115 0 : *action = 0;
2116 : } else {
2117 600 : *action = 1;
2118 : }
2119 : return 0;
2120 : }
2121 :
2122 : /*
2123 : * Remove a name from the leaf attribute list structure.
2124 : *
2125 : * Return 1 if leaf is less than 37% full, 0 if >= 37% full.
2126 : * If two leaves are 37% full, when combined they will leave 25% free.
2127 : */
2128 : int
2129 29118891 : xfs_attr3_leaf_remove(
2130 : struct xfs_buf *bp,
2131 : struct xfs_da_args *args)
2132 : {
2133 29118891 : struct xfs_attr_leafblock *leaf;
2134 29118891 : struct xfs_attr3_icleaf_hdr ichdr;
2135 29118891 : struct xfs_attr_leaf_entry *entry;
2136 29118891 : int before;
2137 29118891 : int after;
2138 29118891 : int smallest;
2139 29118891 : int entsize;
2140 29118891 : int tablesize;
2141 29118891 : int tmp;
2142 29118891 : int i;
2143 :
2144 29118891 : trace_xfs_attr_leaf_remove(args);
2145 :
2146 29105970 : leaf = bp->b_addr;
2147 29105970 : xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
2148 :
2149 29106389 : ASSERT(ichdr.count > 0 && ichdr.count < args->geo->blksize / 8);
2150 29106389 : ASSERT(args->index >= 0 && args->index < ichdr.count);
2151 58212802 : ASSERT(ichdr.firstused >= ichdr.count * sizeof(*entry) +
2152 : xfs_attr3_leaf_hdr_size(leaf));
2153 :
2154 29106389 : entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
2155 :
2156 29106389 : ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused);
2157 29106389 : ASSERT(be16_to_cpu(entry->nameidx) < args->geo->blksize);
2158 :
2159 : /*
2160 : * Scan through free region table:
2161 : * check for adjacency of free'd entry with an existing one,
2162 : * find smallest free region in case we need to replace it,
2163 : * adjust any map that borders the entry table,
2164 : */
2165 29106389 : tablesize = ichdr.count * sizeof(xfs_attr_leaf_entry_t)
2166 29106389 : + xfs_attr3_leaf_hdr_size(leaf);
2167 29106389 : tmp = ichdr.freemap[0].size;
2168 29106389 : before = after = -1;
2169 29106389 : smallest = XFS_ATTR_LEAF_MAPSIZE - 1;
2170 29106389 : entsize = xfs_attr_leaf_entsize(leaf, args->index);
2171 116408777 : for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
2172 87285946 : ASSERT(ichdr.freemap[i].base < args->geo->blksize);
2173 87279722 : ASSERT(ichdr.freemap[i].size < args->geo->blksize);
2174 87282564 : if (ichdr.freemap[i].base == tablesize) {
2175 29062768 : ichdr.freemap[i].base -= sizeof(xfs_attr_leaf_entry_t);
2176 29061930 : ichdr.freemap[i].size += sizeof(xfs_attr_leaf_entry_t);
2177 : }
2178 :
2179 87284193 : if (ichdr.freemap[i].base + ichdr.freemap[i].size ==
2180 87292588 : be16_to_cpu(entry->nameidx)) {
2181 : before = i;
2182 82723344 : } else if (ichdr.freemap[i].base ==
2183 82732620 : (be16_to_cpu(entry->nameidx) + entsize)) {
2184 : after = i;
2185 79812509 : } else if (ichdr.freemap[i].size < tmp) {
2186 41389565 : tmp = ichdr.freemap[i].size;
2187 41389565 : smallest = i;
2188 : }
2189 : }
2190 :
2191 : /*
2192 : * Coalesce adjacent freemap regions,
2193 : * or replace the smallest region.
2194 : */
2195 29122831 : if ((before >= 0) || (after >= 0)) {
2196 7121880 : if ((before >= 0) && (after >= 0)) {
2197 366820 : ichdr.freemap[before].size += entsize;
2198 366823 : ichdr.freemap[before].size += ichdr.freemap[after].size;
2199 366820 : ichdr.freemap[after].base = 0;
2200 366819 : ichdr.freemap[after].size = 0;
2201 6755060 : } else if (before >= 0) {
2202 4201914 : ichdr.freemap[before].size += entsize;
2203 : } else {
2204 2553146 : ichdr.freemap[after].base = be16_to_cpu(entry->nameidx);
2205 2553133 : ichdr.freemap[after].size += entsize;
2206 : }
2207 : } else {
2208 : /*
2209 : * Replace smallest region (if it is smaller than free'd entry)
2210 : */
2211 22000951 : if (ichdr.freemap[smallest].size < entsize) {
2212 18225077 : ichdr.freemap[smallest].base = be16_to_cpu(entry->nameidx);
2213 18224790 : ichdr.freemap[smallest].size = entsize;
2214 : }
2215 : }
2216 :
2217 : /*
2218 : * Did we remove the first entry?
2219 : */
2220 29122115 : if (be16_to_cpu(entry->nameidx) == ichdr.firstused)
2221 : smallest = 1;
2222 : else
2223 27196918 : smallest = 0;
2224 :
2225 : /*
2226 : * Compress the remaining entries and zero out the removed stuff.
2227 : */
2228 29122115 : memset(xfs_attr3_leaf_name(leaf, args->index), 0, entsize);
2229 29122115 : ichdr.usedbytes -= entsize;
2230 58244230 : xfs_trans_log_buf(args->trans, bp,
2231 58244230 : XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index),
2232 : entsize));
2233 :
2234 29118396 : tmp = (ichdr.count - args->index) * sizeof(xfs_attr_leaf_entry_t);
2235 58236792 : memmove(entry, entry + 1, tmp);
2236 29118396 : ichdr.count--;
2237 29118396 : xfs_trans_log_buf(args->trans, bp,
2238 29118396 : XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(xfs_attr_leaf_entry_t)));
2239 :
2240 29129133 : entry = &xfs_attr3_leaf_entryp(leaf)[ichdr.count];
2241 29129133 : memset(entry, 0, sizeof(xfs_attr_leaf_entry_t));
2242 :
2243 : /*
2244 : * If we removed the first entry, re-find the first used byte
2245 : * in the name area. Note that if the entry was the "firstused",
2246 : * then we don't have a "hole" in our block resulting from
2247 : * removing the name.
2248 : */
2249 29129133 : if (smallest) {
2250 1915478 : tmp = args->geo->blksize;
2251 1915478 : entry = xfs_attr3_leaf_entryp(leaf);
2252 24614113 : for (i = ichdr.count - 1; i >= 0; entry++, i--) {
2253 22698597 : ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused);
2254 22698597 : ASSERT(be16_to_cpu(entry->nameidx) < args->geo->blksize);
2255 :
2256 22698635 : if (be16_to_cpu(entry->nameidx) < tmp)
2257 : tmp = be16_to_cpu(entry->nameidx);
2258 : }
2259 1915516 : ichdr.firstused = tmp;
2260 1915516 : ASSERT(ichdr.firstused != 0);
2261 : } else {
2262 27213655 : ichdr.holes = 1; /* mark as needing compaction */
2263 : }
2264 29129171 : xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr);
2265 29084986 : xfs_trans_log_buf(args->trans, bp,
2266 29084986 : XFS_DA_LOGRANGE(leaf, &leaf->hdr,
2267 : xfs_attr3_leaf_hdr_size(leaf)));
2268 :
2269 : /*
2270 : * Check if leaf is less than 50% full, caller may want to
2271 : * "join" the leaf with a sibling if so.
2272 : */
2273 29130191 : tmp = ichdr.usedbytes + xfs_attr3_leaf_hdr_size(leaf) +
2274 29130191 : ichdr.count * sizeof(xfs_attr_leaf_entry_t);
2275 :
2276 29130191 : return tmp < args->geo->magicpct; /* leaf is < 37% full */
2277 : }
2278 :
2279 : /*
2280 : * Move all the attribute list entries from drop_leaf into save_leaf.
2281 : */
2282 : void
2283 600 : xfs_attr3_leaf_unbalance(
2284 : struct xfs_da_state *state,
2285 : struct xfs_da_state_blk *drop_blk,
2286 : struct xfs_da_state_blk *save_blk)
2287 : {
2288 600 : struct xfs_attr_leafblock *drop_leaf = drop_blk->bp->b_addr;
2289 600 : struct xfs_attr_leafblock *save_leaf = save_blk->bp->b_addr;
2290 600 : struct xfs_attr3_icleaf_hdr drophdr;
2291 600 : struct xfs_attr3_icleaf_hdr savehdr;
2292 600 : struct xfs_attr_leaf_entry *entry;
2293 :
2294 600 : trace_xfs_attr_leaf_unbalance(state->args);
2295 :
2296 600 : xfs_attr3_leaf_hdr_from_disk(state->args->geo, &drophdr, drop_leaf);
2297 600 : xfs_attr3_leaf_hdr_from_disk(state->args->geo, &savehdr, save_leaf);
2298 600 : entry = xfs_attr3_leaf_entryp(drop_leaf);
2299 :
2300 : /*
2301 : * Save last hashval from dying block for later Btree fixup.
2302 : */
2303 600 : drop_blk->hashval = be32_to_cpu(entry[drophdr.count - 1].hashval);
2304 :
2305 : /*
2306 : * Check if we need a temp buffer, or can we do it in place.
2307 : * Note that we don't check "leaf" for holes because we will
2308 : * always be dropping it, toosmall() decided that for us already.
2309 : */
2310 600 : if (savehdr.holes == 0) {
2311 : /*
2312 : * dest leaf has no holes, so we add there. May need
2313 : * to make some room in the entry array.
2314 : */
2315 0 : if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
2316 : drop_blk->bp, &drophdr)) {
2317 0 : xfs_attr3_leaf_moveents(state->args,
2318 : drop_leaf, &drophdr, 0,
2319 : save_leaf, &savehdr, 0,
2320 : drophdr.count);
2321 : } else {
2322 0 : xfs_attr3_leaf_moveents(state->args,
2323 : drop_leaf, &drophdr, 0,
2324 : save_leaf, &savehdr,
2325 0 : savehdr.count, drophdr.count);
2326 : }
2327 : } else {
2328 : /*
2329 : * Destination has holes, so we make a temporary copy
2330 : * of the leaf and add them both to that.
2331 : */
2332 600 : struct xfs_attr_leafblock *tmp_leaf;
2333 600 : struct xfs_attr3_icleaf_hdr tmphdr;
2334 :
2335 600 : tmp_leaf = kmem_zalloc(state->args->geo->blksize, 0);
2336 :
2337 : /*
2338 : * Copy the header into the temp leaf so that all the stuff
2339 : * not in the incore header is present and gets copied back in
2340 : * once we've moved all the entries.
2341 : */
2342 1800 : memcpy(tmp_leaf, save_leaf, xfs_attr3_leaf_hdr_size(save_leaf));
2343 :
2344 600 : memset(&tmphdr, 0, sizeof(tmphdr));
2345 600 : tmphdr.magic = savehdr.magic;
2346 600 : tmphdr.forw = savehdr.forw;
2347 600 : tmphdr.back = savehdr.back;
2348 600 : tmphdr.firstused = state->args->geo->blksize;
2349 :
2350 : /* write the header to the temp buffer to initialise it */
2351 600 : xfs_attr3_leaf_hdr_to_disk(state->args->geo, tmp_leaf, &tmphdr);
2352 :
2353 600 : if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
2354 : drop_blk->bp, &drophdr)) {
2355 213 : xfs_attr3_leaf_moveents(state->args,
2356 : drop_leaf, &drophdr, 0,
2357 : tmp_leaf, &tmphdr, 0,
2358 213 : drophdr.count);
2359 213 : xfs_attr3_leaf_moveents(state->args,
2360 : save_leaf, &savehdr, 0,
2361 213 : tmp_leaf, &tmphdr, tmphdr.count,
2362 213 : savehdr.count);
2363 : } else {
2364 387 : xfs_attr3_leaf_moveents(state->args,
2365 : save_leaf, &savehdr, 0,
2366 : tmp_leaf, &tmphdr, 0,
2367 387 : savehdr.count);
2368 387 : xfs_attr3_leaf_moveents(state->args,
2369 : drop_leaf, &drophdr, 0,
2370 387 : tmp_leaf, &tmphdr, tmphdr.count,
2371 387 : drophdr.count);
2372 : }
2373 1200 : memcpy(save_leaf, tmp_leaf, state->args->geo->blksize);
2374 600 : savehdr = tmphdr; /* struct copy */
2375 600 : kmem_free(tmp_leaf);
2376 : }
2377 :
2378 600 : xfs_attr3_leaf_hdr_to_disk(state->args->geo, save_leaf, &savehdr);
2379 600 : xfs_trans_log_buf(state->args->trans, save_blk->bp, 0,
2380 600 : state->args->geo->blksize - 1);
2381 :
2382 : /*
2383 : * Copy out last hashval in each block for B-tree code.
2384 : */
2385 600 : entry = xfs_attr3_leaf_entryp(save_leaf);
2386 600 : save_blk->hashval = be32_to_cpu(entry[savehdr.count - 1].hashval);
2387 600 : }
2388 :
2389 : /*========================================================================
2390 : * Routines used for finding things in the Btree.
2391 : *========================================================================*/
2392 :
2393 : /*
2394 : * Look up a name in a leaf attribute list structure.
2395 : * This is the internal routine, it uses the caller's buffer.
2396 : *
2397 : * Note that duplicate keys are allowed, but only check within the
2398 : * current leaf node. The Btree code must check in adjacent leaf nodes.
2399 : *
2400 : * Return in args->index the index into the entry[] array of either
2401 : * the found entry, or where the entry should have been (insert before
2402 : * that entry).
2403 : *
2404 : * Don't change the args->value unless we find the attribute.
2405 : */
2406 : int
2407 535586919 : xfs_attr3_leaf_lookup_int(
2408 : struct xfs_buf *bp,
2409 : struct xfs_da_args *args)
2410 : {
2411 535586919 : struct xfs_attr_leafblock *leaf;
2412 535586919 : struct xfs_attr3_icleaf_hdr ichdr;
2413 535586919 : struct xfs_attr_leaf_entry *entry;
2414 535586919 : struct xfs_attr_leaf_entry *entries;
2415 535586919 : struct xfs_attr_leaf_name_local *name_loc;
2416 535586919 : struct xfs_attr_leaf_name_remote *name_rmt;
2417 535586919 : xfs_dahash_t hashval;
2418 535586919 : int probe;
2419 535586919 : int span;
2420 :
2421 535586919 : trace_xfs_attr_leaf_lookup(args);
2422 :
2423 535432658 : leaf = bp->b_addr;
2424 535432658 : xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
2425 535733931 : entries = xfs_attr3_leaf_entryp(leaf);
2426 535733931 : if (ichdr.count >= args->geo->blksize / 8) {
2427 0 : xfs_buf_mark_corrupt(bp);
2428 0 : return -EFSCORRUPTED;
2429 : }
2430 :
2431 : /*
2432 : * Binary search. (note: small blocks will skip this loop)
2433 : */
2434 535733931 : hashval = args->hashval;
2435 535733931 : probe = span = ichdr.count / 2;
2436 705879189 : for (entry = &entries[probe]; span > 4; entry = &entries[probe]) {
2437 175135200 : span /= 2;
2438 175135200 : if (be32_to_cpu(entry->hashval) < hashval)
2439 108360807 : probe += span;
2440 66774393 : else if (be32_to_cpu(entry->hashval) > hashval)
2441 61784451 : probe -= span;
2442 : else
2443 : break;
2444 : }
2445 535733931 : if (!(probe >= 0 && (!ichdr.count || probe < ichdr.count))) {
2446 0 : xfs_buf_mark_corrupt(bp);
2447 0 : return -EFSCORRUPTED;
2448 : }
2449 535733931 : if (!(span <= 4 || be32_to_cpu(entry->hashval) == hashval)) {
2450 0 : xfs_buf_mark_corrupt(bp);
2451 0 : return -EFSCORRUPTED;
2452 : }
2453 :
2454 : /*
2455 : * Since we may have duplicate hashval's, find the first matching
2456 : * hashval in the leaf.
2457 : */
2458 2150104173 : while (probe > 0 && be32_to_cpu(entry->hashval) >= hashval) {
2459 1614370242 : entry--;
2460 1614370242 : probe--;
2461 : }
2462 902376030 : while (probe < ichdr.count &&
2463 835738760 : be32_to_cpu(entry->hashval) < hashval) {
2464 366642099 : entry++;
2465 366642099 : probe++;
2466 : }
2467 535733931 : if (probe == ichdr.count || be32_to_cpu(entry->hashval) != hashval) {
2468 102186608 : args->index = probe;
2469 102186608 : return -ENOATTR;
2470 : }
2471 :
2472 : /*
2473 : * Duplicate keys may be present, so search all of them for a match.
2474 : */
2475 3386738834 : for (; probe < ichdr.count && (be32_to_cpu(entry->hashval) == hashval);
2476 2953191511 : entry++, probe++) {
2477 : /*
2478 : * GROT: Add code to remove incomplete entries.
2479 : */
2480 3017774973 : if (entry->flags & XFS_ATTR_LOCAL) {
2481 3017773761 : name_loc = xfs_attr3_leaf_name_local(leaf, probe);
2482 3017768919 : if (!xfs_attr_match(args, name_loc->namelen,
2483 3017773761 : name_loc->nameval, entry->flags))
2484 2953191501 : continue;
2485 64577418 : args->index = probe;
2486 64577418 : return -EEXIST;
2487 : } else {
2488 1212 : name_rmt = xfs_attr3_leaf_name_remote(leaf, probe);
2489 1212 : if (!xfs_attr_match(args, name_rmt->namelen,
2490 1212 : name_rmt->name, entry->flags))
2491 10 : continue;
2492 1202 : args->index = probe;
2493 1202 : args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen);
2494 1202 : args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
2495 2404 : args->rmtblkcnt = xfs_attr3_rmt_blocks(
2496 1202 : args->dp->i_mount,
2497 : args->rmtvaluelen);
2498 1202 : return -EEXIST;
2499 : }
2500 : }
2501 368963861 : args->index = probe;
2502 368963861 : return -ENOATTR;
2503 : }
2504 :
2505 : /*
2506 : * Get the value associated with an attribute name from a leaf attribute
2507 : * list structure.
2508 : *
2509 : * If args->valuelen is zero, only the length needs to be returned. Unlike a
2510 : * lookup, we only return an error if the attribute does not exist or we can't
2511 : * retrieve the value.
2512 : */
2513 : int
2514 5706029 : xfs_attr3_leaf_getvalue(
2515 : struct xfs_buf *bp,
2516 : struct xfs_da_args *args)
2517 : {
2518 5706029 : struct xfs_attr_leafblock *leaf;
2519 5706029 : struct xfs_attr3_icleaf_hdr ichdr;
2520 5706029 : struct xfs_attr_leaf_entry *entry;
2521 5706029 : struct xfs_attr_leaf_name_local *name_loc;
2522 5706029 : struct xfs_attr_leaf_name_remote *name_rmt;
2523 :
2524 5706029 : leaf = bp->b_addr;
2525 5706029 : xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
2526 5705730 : ASSERT(ichdr.count < args->geo->blksize / 8);
2527 5705730 : ASSERT(args->index < ichdr.count);
2528 :
2529 5705730 : entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
2530 5705730 : if (entry->flags & XFS_ATTR_LOCAL) {
2531 5704792 : name_loc = xfs_attr3_leaf_name_local(leaf, args->index);
2532 5704792 : ASSERT(name_loc->namelen == args->namelen);
2533 11409584 : ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0);
2534 5704792 : return xfs_attr_copy_value(args,
2535 5704792 : &name_loc->nameval[args->namelen],
2536 5704792 : be16_to_cpu(name_loc->valuelen));
2537 : }
2538 :
2539 938 : name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
2540 938 : ASSERT(name_rmt->namelen == args->namelen);
2541 1876 : ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0);
2542 938 : args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen);
2543 938 : args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
2544 938 : args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount,
2545 : args->rmtvaluelen);
2546 938 : return xfs_attr_copy_value(args, NULL, args->rmtvaluelen);
2547 : }
2548 :
2549 : /*========================================================================
2550 : * Utility routines.
2551 : *========================================================================*/
2552 :
2553 : /*
2554 : * Move the indicated entries from one leaf to another.
2555 : * NOTE: this routine modifies both source and destination leaves.
2556 : */
2557 : /*ARGSUSED*/
2558 : STATIC void
2559 282181 : xfs_attr3_leaf_moveents(
2560 : struct xfs_da_args *args,
2561 : struct xfs_attr_leafblock *leaf_s,
2562 : struct xfs_attr3_icleaf_hdr *ichdr_s,
2563 : int start_s,
2564 : struct xfs_attr_leafblock *leaf_d,
2565 : struct xfs_attr3_icleaf_hdr *ichdr_d,
2566 : int start_d,
2567 : int count)
2568 : {
2569 282181 : struct xfs_attr_leaf_entry *entry_s;
2570 282181 : struct xfs_attr_leaf_entry *entry_d;
2571 282181 : int desti;
2572 282181 : int tmp;
2573 282181 : int i;
2574 :
2575 : /*
2576 : * Check for nothing to do.
2577 : */
2578 282181 : if (count == 0)
2579 : return;
2580 :
2581 : /*
2582 : * Set up environment.
2583 : */
2584 282181 : ASSERT(ichdr_s->magic == XFS_ATTR_LEAF_MAGIC ||
2585 : ichdr_s->magic == XFS_ATTR3_LEAF_MAGIC);
2586 282181 : ASSERT(ichdr_s->magic == ichdr_d->magic);
2587 282181 : ASSERT(ichdr_s->count > 0 && ichdr_s->count < args->geo->blksize / 8);
2588 564361 : ASSERT(ichdr_s->firstused >= (ichdr_s->count * sizeof(*entry_s))
2589 : + xfs_attr3_leaf_hdr_size(leaf_s));
2590 282181 : ASSERT(ichdr_d->count < args->geo->blksize / 8);
2591 564362 : ASSERT(ichdr_d->firstused >= (ichdr_d->count * sizeof(*entry_d))
2592 : + xfs_attr3_leaf_hdr_size(leaf_d));
2593 :
2594 282181 : ASSERT(start_s < ichdr_s->count);
2595 282181 : ASSERT(start_d <= ichdr_d->count);
2596 282181 : ASSERT(count <= ichdr_s->count);
2597 :
2598 :
2599 : /*
2600 : * Move the entries in the destination leaf up to make a hole?
2601 : */
2602 282181 : if (start_d < ichdr_d->count) {
2603 0 : tmp = ichdr_d->count - start_d;
2604 0 : tmp *= sizeof(xfs_attr_leaf_entry_t);
2605 0 : entry_s = &xfs_attr3_leaf_entryp(leaf_d)[start_d];
2606 0 : entry_d = &xfs_attr3_leaf_entryp(leaf_d)[start_d + count];
2607 0 : memmove(entry_d, entry_s, tmp);
2608 : }
2609 :
2610 : /*
2611 : * Copy all entry's in the same (sorted) order,
2612 : * but allocate attribute info packed and in sequence.
2613 : */
2614 282181 : entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
2615 282181 : entry_d = &xfs_attr3_leaf_entryp(leaf_d)[start_d];
2616 282181 : desti = start_d;
2617 10734051 : for (i = 0; i < count; entry_s++, entry_d++, desti++, i++) {
2618 10451866 : ASSERT(be16_to_cpu(entry_s->nameidx) >= ichdr_s->firstused);
2619 10451866 : tmp = xfs_attr_leaf_entsize(leaf_s, start_s + i);
2620 : #ifdef GROT
2621 : /*
2622 : * Code to drop INCOMPLETE entries. Difficult to use as we
2623 : * may also need to change the insertion index. Code turned
2624 : * off for 6.2, should be revisited later.
2625 : */
2626 : if (entry_s->flags & XFS_ATTR_INCOMPLETE) { /* skip partials? */
2627 : memset(xfs_attr3_leaf_name(leaf_s, start_s + i), 0, tmp);
2628 : ichdr_s->usedbytes -= tmp;
2629 : ichdr_s->count -= 1;
2630 : entry_d--; /* to compensate for ++ in loop hdr */
2631 : desti--;
2632 : if ((start_s + i) < offset)
2633 : result++; /* insertion index adjustment */
2634 : } else {
2635 : #endif /* GROT */
2636 10451866 : ichdr_d->firstused -= tmp;
2637 : /* both on-disk, don't endian flip twice */
2638 10451866 : entry_d->hashval = entry_s->hashval;
2639 10451866 : entry_d->nameidx = cpu_to_be16(ichdr_d->firstused);
2640 10451866 : entry_d->flags = entry_s->flags;
2641 10451866 : ASSERT(be16_to_cpu(entry_d->nameidx) + tmp
2642 : <= args->geo->blksize);
2643 10451866 : memmove(xfs_attr3_leaf_name(leaf_d, desti),
2644 : xfs_attr3_leaf_name(leaf_s, start_s + i), tmp);
2645 10451866 : ASSERT(be16_to_cpu(entry_s->nameidx) + tmp
2646 : <= args->geo->blksize);
2647 10451866 : memset(xfs_attr3_leaf_name(leaf_s, start_s + i), 0, tmp);
2648 10451866 : ichdr_s->usedbytes -= tmp;
2649 10451866 : ichdr_d->usedbytes += tmp;
2650 10451866 : ichdr_s->count -= 1;
2651 10451866 : ichdr_d->count += 1;
2652 10451866 : tmp = ichdr_d->count * sizeof(xfs_attr_leaf_entry_t)
2653 10451866 : + xfs_attr3_leaf_hdr_size(leaf_d);
2654 10451866 : ASSERT(ichdr_d->firstused >= tmp);
2655 : #ifdef GROT
2656 : }
2657 : #endif /* GROT */
2658 : }
2659 :
2660 : /*
2661 : * Zero out the entries we just copied.
2662 : */
2663 282185 : if (start_s == ichdr_s->count) {
2664 282185 : tmp = count * sizeof(xfs_attr_leaf_entry_t);
2665 282185 : entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
2666 282185 : ASSERT(((char *)entry_s + tmp) <=
2667 : ((char *)leaf_s + args->geo->blksize));
2668 564370 : memset(entry_s, 0, tmp);
2669 : } else {
2670 : /*
2671 : * Move the remaining entries down to fill the hole,
2672 : * then zero the entries at the top.
2673 : */
2674 0 : tmp = (ichdr_s->count - count) * sizeof(xfs_attr_leaf_entry_t);
2675 0 : entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s + count];
2676 0 : entry_d = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
2677 0 : memmove(entry_d, entry_s, tmp);
2678 :
2679 0 : tmp = count * sizeof(xfs_attr_leaf_entry_t);
2680 0 : entry_s = &xfs_attr3_leaf_entryp(leaf_s)[ichdr_s->count];
2681 0 : ASSERT(((char *)entry_s + tmp) <=
2682 : ((char *)leaf_s + args->geo->blksize));
2683 0 : memset(entry_s, 0, tmp);
2684 : }
2685 :
2686 : /*
2687 : * Fill in the freemap information
2688 : */
2689 282185 : ichdr_d->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_d);
2690 282185 : ichdr_d->freemap[0].base += ichdr_d->count * sizeof(xfs_attr_leaf_entry_t);
2691 282185 : ichdr_d->freemap[0].size = ichdr_d->firstused - ichdr_d->freemap[0].base;
2692 282185 : ichdr_d->freemap[1].base = 0;
2693 282185 : ichdr_d->freemap[2].base = 0;
2694 282185 : ichdr_d->freemap[1].size = 0;
2695 282185 : ichdr_d->freemap[2].size = 0;
2696 282185 : ichdr_s->holes = 1; /* leaf may not be compact */
2697 : }
2698 :
2699 : /*
2700 : * Pick up the last hashvalue from a leaf block.
2701 : */
2702 : xfs_dahash_t
2703 376806215 : xfs_attr_leaf_lasthash(
2704 : struct xfs_buf *bp,
2705 : int *count)
2706 : {
2707 376806215 : struct xfs_attr3_icleaf_hdr ichdr;
2708 376806215 : struct xfs_attr_leaf_entry *entries;
2709 376806215 : struct xfs_mount *mp = bp->b_mount;
2710 :
2711 376806215 : xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, bp->b_addr);
2712 376802835 : entries = xfs_attr3_leaf_entryp(bp->b_addr);
2713 376802835 : if (count)
2714 3384240 : *count = ichdr.count;
2715 376802835 : if (!ichdr.count)
2716 : return 0;
2717 376802800 : return be32_to_cpu(entries[ichdr.count - 1].hashval);
2718 : }
2719 :
2720 : /*
2721 : * Calculate the number of bytes used to store the indicated attribute
2722 : * (whether local or remote only calculate bytes in this block).
2723 : */
2724 : STATIC int
2725 162341773 : xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
2726 : {
2727 162341773 : struct xfs_attr_leaf_entry *entries;
2728 162341773 : xfs_attr_leaf_name_local_t *name_loc;
2729 162341773 : xfs_attr_leaf_name_remote_t *name_rmt;
2730 162341773 : int size;
2731 :
2732 162341773 : entries = xfs_attr3_leaf_entryp(leaf);
2733 162341773 : if (entries[index].flags & XFS_ATTR_LOCAL) {
2734 162336013 : name_loc = xfs_attr3_leaf_name_local(leaf, index);
2735 162336013 : size = xfs_attr_leaf_entsize_local(name_loc->namelen,
2736 162336013 : be16_to_cpu(name_loc->valuelen));
2737 : } else {
2738 5760 : name_rmt = xfs_attr3_leaf_name_remote(leaf, index);
2739 5760 : size = xfs_attr_leaf_entsize_remote(name_rmt->namelen);
2740 : }
2741 162341773 : return size;
2742 : }
2743 :
2744 : /*
2745 : * Calculate the number of bytes that would be required to store the new
2746 : * attribute (whether local or remote only calculate bytes in this block).
2747 : * This routine decides as a side effect whether the attribute will be
2748 : * a "local" or a "remote" attribute.
2749 : */
2750 : int
2751 262487462 : xfs_attr_leaf_newentsize(
2752 : struct xfs_da_args *args,
2753 : int *local)
2754 : {
2755 262487462 : int size;
2756 :
2757 262487462 : size = xfs_attr_leaf_entsize_local(args->namelen, args->valuelen);
2758 262487462 : if (size < xfs_attr_leaf_entsize_local_max(args->geo->blksize)) {
2759 262475768 : if (local)
2760 140787979 : *local = 1;
2761 262475768 : return size;
2762 : }
2763 11694 : if (local)
2764 6022 : *local = 0;
2765 11694 : return xfs_attr_leaf_entsize_remote(args->namelen);
2766 : }
2767 :
2768 :
2769 : /*========================================================================
2770 : * Manage the INCOMPLETE flag in a leaf entry
2771 : *========================================================================*/
2772 :
2773 : /*
2774 : * Clear the INCOMPLETE flag on an entry in a leaf block.
2775 : */
2776 : int
2777 2826 : xfs_attr3_leaf_clearflag(
2778 : struct xfs_da_args *args)
2779 : {
2780 2826 : struct xfs_attr_leafblock *leaf;
2781 2826 : struct xfs_attr_leaf_entry *entry;
2782 2826 : struct xfs_attr_leaf_name_remote *name_rmt;
2783 2826 : struct xfs_buf *bp;
2784 2826 : int error;
2785 : #ifdef DEBUG
2786 2826 : struct xfs_attr3_icleaf_hdr ichdr;
2787 2826 : xfs_attr_leaf_name_local_t *name_loc;
2788 2826 : int namelen;
2789 2826 : char *name;
2790 : #endif /* DEBUG */
2791 :
2792 2826 : trace_xfs_attr_leaf_clearflag(args);
2793 : /*
2794 : * Set up the operation.
2795 : */
2796 2826 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, &bp);
2797 2826 : if (error)
2798 : return error;
2799 :
2800 2826 : leaf = bp->b_addr;
2801 2826 : entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
2802 2826 : ASSERT(entry->flags & XFS_ATTR_INCOMPLETE);
2803 :
2804 : #ifdef DEBUG
2805 2826 : xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
2806 2826 : ASSERT(args->index < ichdr.count);
2807 2826 : ASSERT(args->index >= 0);
2808 :
2809 2826 : if (entry->flags & XFS_ATTR_LOCAL) {
2810 0 : name_loc = xfs_attr3_leaf_name_local(leaf, args->index);
2811 0 : namelen = name_loc->namelen;
2812 0 : name = (char *)name_loc->nameval;
2813 : } else {
2814 2826 : name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
2815 2826 : namelen = name_rmt->namelen;
2816 2826 : name = (char *)name_rmt->name;
2817 : }
2818 2826 : ASSERT(be32_to_cpu(entry->hashval) == args->hashval);
2819 2826 : ASSERT(namelen == args->namelen);
2820 5652 : ASSERT(memcmp(name, args->name, namelen) == 0);
2821 : #endif /* DEBUG */
2822 :
2823 2826 : entry->flags &= ~XFS_ATTR_INCOMPLETE;
2824 2826 : xfs_trans_log_buf(args->trans, bp,
2825 2826 : XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
2826 :
2827 2826 : if (args->rmtblkno) {
2828 2826 : ASSERT((entry->flags & XFS_ATTR_LOCAL) == 0);
2829 2826 : name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
2830 2826 : name_rmt->valueblk = cpu_to_be32(args->rmtblkno);
2831 2826 : name_rmt->valuelen = cpu_to_be32(args->rmtvaluelen);
2832 2826 : xfs_trans_log_buf(args->trans, bp,
2833 : XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt)));
2834 : }
2835 :
2836 : return 0;
2837 : }
2838 :
2839 : /*
2840 : * Set the INCOMPLETE flag on an entry in a leaf block.
2841 : */
2842 : int
2843 382777 : xfs_attr3_leaf_setflag(
2844 : struct xfs_da_args *args)
2845 : {
2846 382777 : struct xfs_attr_leafblock *leaf;
2847 382777 : struct xfs_attr_leaf_entry *entry;
2848 382777 : struct xfs_attr_leaf_name_remote *name_rmt;
2849 382777 : struct xfs_buf *bp;
2850 382777 : int error;
2851 : #ifdef DEBUG
2852 382777 : struct xfs_attr3_icleaf_hdr ichdr;
2853 : #endif
2854 :
2855 382777 : trace_xfs_attr_leaf_setflag(args);
2856 :
2857 : /*
2858 : * Set up the operation.
2859 : */
2860 382757 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, &bp);
2861 382789 : if (error)
2862 : return error;
2863 :
2864 382790 : leaf = bp->b_addr;
2865 : #ifdef DEBUG
2866 382790 : xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
2867 382783 : ASSERT(args->index < ichdr.count);
2868 382783 : ASSERT(args->index >= 0);
2869 : #endif
2870 382783 : entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
2871 :
2872 382783 : ASSERT((entry->flags & XFS_ATTR_INCOMPLETE) == 0);
2873 382783 : entry->flags |= XFS_ATTR_INCOMPLETE;
2874 382783 : xfs_trans_log_buf(args->trans, bp,
2875 382783 : XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
2876 382785 : if ((entry->flags & XFS_ATTR_LOCAL) == 0) {
2877 68 : name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
2878 68 : name_rmt->valueblk = 0;
2879 68 : name_rmt->valuelen = 0;
2880 68 : xfs_trans_log_buf(args->trans, bp,
2881 : XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt)));
2882 : }
2883 :
2884 : return 0;
2885 : }
2886 :
2887 : /*
2888 : * In a single transaction, clear the INCOMPLETE flag on the leaf entry
2889 : * given by args->blkno/index and set the INCOMPLETE flag on the leaf
2890 : * entry given by args->blkno2/index2.
2891 : *
2892 : * Note that they could be in different blocks, or in the same block.
2893 : */
2894 : int
2895 11237848 : xfs_attr3_leaf_flipflags(
2896 : struct xfs_da_args *args)
2897 : {
2898 11237848 : struct xfs_attr_leafblock *leaf1;
2899 11237848 : struct xfs_attr_leafblock *leaf2;
2900 11237848 : struct xfs_attr_leaf_entry *entry1;
2901 11237848 : struct xfs_attr_leaf_entry *entry2;
2902 11237848 : struct xfs_attr_leaf_name_remote *name_rmt;
2903 11237848 : struct xfs_buf *bp1;
2904 11237848 : struct xfs_buf *bp2;
2905 11237848 : int error;
2906 : #ifdef DEBUG
2907 11237848 : struct xfs_attr3_icleaf_hdr ichdr1;
2908 11237848 : struct xfs_attr3_icleaf_hdr ichdr2;
2909 11237848 : xfs_attr_leaf_name_local_t *name_loc;
2910 11237848 : int namelen1, namelen2;
2911 11237848 : char *name1, *name2;
2912 : #endif /* DEBUG */
2913 :
2914 11237848 : trace_xfs_attr_leaf_flipflags(args);
2915 :
2916 : /*
2917 : * Read the block containing the "old" attr
2918 : */
2919 11230896 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, &bp1);
2920 11239042 : if (error)
2921 : return error;
2922 :
2923 : /*
2924 : * Read the block containing the "new" attr, if it is different
2925 : */
2926 11239042 : if (args->blkno2 != args->blkno) {
2927 123 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno2,
2928 : &bp2);
2929 123 : if (error)
2930 : return error;
2931 : } else {
2932 11238919 : bp2 = bp1;
2933 : }
2934 :
2935 11239042 : leaf1 = bp1->b_addr;
2936 11239042 : entry1 = &xfs_attr3_leaf_entryp(leaf1)[args->index];
2937 :
2938 11239042 : leaf2 = bp2->b_addr;
2939 11239042 : entry2 = &xfs_attr3_leaf_entryp(leaf2)[args->index2];
2940 :
2941 : #ifdef DEBUG
2942 11239042 : xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr1, leaf1);
2943 11232686 : ASSERT(args->index < ichdr1.count);
2944 11232686 : ASSERT(args->index >= 0);
2945 :
2946 11232686 : xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr2, leaf2);
2947 11234237 : ASSERT(args->index2 < ichdr2.count);
2948 11234237 : ASSERT(args->index2 >= 0);
2949 :
2950 11234237 : if (entry1->flags & XFS_ATTR_LOCAL) {
2951 11234227 : name_loc = xfs_attr3_leaf_name_local(leaf1, args->index);
2952 11234227 : namelen1 = name_loc->namelen;
2953 11234227 : name1 = (char *)name_loc->nameval;
2954 : } else {
2955 10 : name_rmt = xfs_attr3_leaf_name_remote(leaf1, args->index);
2956 10 : namelen1 = name_rmt->namelen;
2957 10 : name1 = (char *)name_rmt->name;
2958 : }
2959 11234237 : if (entry2->flags & XFS_ATTR_LOCAL) {
2960 11233456 : name_loc = xfs_attr3_leaf_name_local(leaf2, args->index2);
2961 11233456 : namelen2 = name_loc->namelen;
2962 11233456 : name2 = (char *)name_loc->nameval;
2963 : } else {
2964 782 : name_rmt = xfs_attr3_leaf_name_remote(leaf2, args->index2);
2965 782 : namelen2 = name_rmt->namelen;
2966 782 : name2 = (char *)name_rmt->name;
2967 : }
2968 11234237 : ASSERT(be32_to_cpu(entry1->hashval) == be32_to_cpu(entry2->hashval));
2969 11234237 : ASSERT(namelen1 == namelen2);
2970 22468474 : ASSERT(memcmp(name1, name2, namelen1) == 0);
2971 : #endif /* DEBUG */
2972 :
2973 11234237 : ASSERT(entry1->flags & XFS_ATTR_INCOMPLETE);
2974 11234237 : ASSERT((entry2->flags & XFS_ATTR_INCOMPLETE) == 0);
2975 :
2976 11234237 : entry1->flags &= ~XFS_ATTR_INCOMPLETE;
2977 11234237 : xfs_trans_log_buf(args->trans, bp1,
2978 11234237 : XFS_DA_LOGRANGE(leaf1, entry1, sizeof(*entry1)));
2979 11241303 : if (args->rmtblkno) {
2980 10 : ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0);
2981 10 : name_rmt = xfs_attr3_leaf_name_remote(leaf1, args->index);
2982 10 : name_rmt->valueblk = cpu_to_be32(args->rmtblkno);
2983 10 : name_rmt->valuelen = cpu_to_be32(args->rmtvaluelen);
2984 10 : xfs_trans_log_buf(args->trans, bp1,
2985 : XFS_DA_LOGRANGE(leaf1, name_rmt, sizeof(*name_rmt)));
2986 : }
2987 :
2988 11241303 : entry2->flags |= XFS_ATTR_INCOMPLETE;
2989 11241303 : xfs_trans_log_buf(args->trans, bp2,
2990 11241303 : XFS_DA_LOGRANGE(leaf2, entry2, sizeof(*entry2)));
2991 11242524 : if ((entry2->flags & XFS_ATTR_LOCAL) == 0) {
2992 20 : name_rmt = xfs_attr3_leaf_name_remote(leaf2, args->index2);
2993 20 : name_rmt->valueblk = 0;
2994 20 : name_rmt->valuelen = 0;
2995 20 : xfs_trans_log_buf(args->trans, bp2,
2996 : XFS_DA_LOGRANGE(leaf2, name_rmt, sizeof(*name_rmt)));
2997 : }
2998 :
2999 : return 0;
3000 : }
|