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 939759227 : 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 939759227 : struct xfs_attr3_leaf_hdr *hdr3;
100 :
101 939759227 : if (from->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)) {
102 939759227 : hdr3 = (struct xfs_attr3_leaf_hdr *) from;
103 939759227 : 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 939759227 : 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 939759227 : }
119 :
120 : static void
121 83304104 : 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 83304104 : struct xfs_attr3_leaf_hdr *hdr3;
127 83304104 : uint32_t firstused;
128 :
129 : /* magic value should only be seen on disk */
130 83304104 : 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 83304104 : firstused = from->firstused;
138 83304104 : if (firstused > USHRT_MAX) {
139 0 : ASSERT(from->firstused == geo->blksize);
140 : firstused = XFS_ATTR3_LEAF_NULLOFF;
141 : }
142 :
143 83304104 : if (from->magic == XFS_ATTR3_LEAF_MAGIC) {
144 83304104 : hdr3 = (struct xfs_attr3_leaf_hdr *) to;
145 83304104 : hdr3->firstused = cpu_to_be16(firstused);
146 : } else {
147 0 : to->hdr.firstused = cpu_to_be16(firstused);
148 : }
149 83304104 : }
150 :
151 : void
152 939525417 : 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 939525417 : int i;
158 :
159 939525417 : 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 939525417 : if (from->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)) {
163 939525417 : struct xfs_attr3_leaf_hdr *hdr3 = (struct xfs_attr3_leaf_hdr *)from;
164 :
165 939525417 : to->forw = be32_to_cpu(hdr3->info.hdr.forw);
166 939525417 : to->back = be32_to_cpu(hdr3->info.hdr.back);
167 939525417 : to->magic = be16_to_cpu(hdr3->info.hdr.magic);
168 939525417 : to->count = be16_to_cpu(hdr3->count);
169 939525417 : to->usedbytes = be16_to_cpu(hdr3->usedbytes);
170 939525417 : xfs_attr3_leaf_firstused_from_disk(geo, to, from);
171 939693087 : to->holes = hdr3->holes;
172 :
173 3757666384 : for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
174 5635867482 : to->freemap[i].base = be16_to_cpu(hdr3->freemap[i].base);
175 5636010565 : 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 83284893 : 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 83284893 : int i;
200 :
201 83284893 : ASSERT(from->magic == XFS_ATTR_LEAF_MAGIC ||
202 : from->magic == XFS_ATTR3_LEAF_MAGIC);
203 :
204 83284893 : if (from->magic == XFS_ATTR3_LEAF_MAGIC) {
205 83284893 : struct xfs_attr3_leaf_hdr *hdr3 = (struct xfs_attr3_leaf_hdr *)to;
206 :
207 83284893 : hdr3->info.hdr.forw = cpu_to_be32(from->forw);
208 83284893 : hdr3->info.hdr.back = cpu_to_be32(from->back);
209 83284893 : hdr3->info.hdr.magic = cpu_to_be16(from->magic);
210 83284893 : hdr3->count = cpu_to_be16(from->count);
211 83284893 : hdr3->usedbytes = cpu_to_be16(from->usedbytes);
212 83284893 : xfs_attr3_leaf_firstused_to_disk(geo, to, from);
213 83293284 : hdr3->holes = from->holes;
214 83293284 : hdr3->pad1 = 0;
215 :
216 333115011 : for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
217 499597275 : hdr3->freemap[i].base = cpu_to_be16(from->freemap[i].base);
218 499632885 : 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 239894251 : 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 239894251 : struct xfs_attr_leaf_name_local *lentry;
248 239894251 : struct xfs_attr_leaf_name_remote *rentry;
249 239894251 : char *name_end;
250 239894251 : unsigned int nameidx;
251 239894251 : unsigned int namesize;
252 239894251 : __u32 hashval;
253 :
254 : /* hash order check */
255 239894251 : hashval = be32_to_cpu(ent->hashval);
256 239894251 : if (hashval < *last_hashval)
257 0 : return __this_address;
258 239894251 : *last_hashval = hashval;
259 :
260 239894251 : nameidx = be16_to_cpu(ent->nameidx);
261 239894251 : if (nameidx < leafhdr->firstused || nameidx >= mp->m_attr_geo->blksize)
262 9 : 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 239895257 : if (ent->flags & XFS_ATTR_LOCAL) {
269 239894544 : lentry = xfs_attr3_leaf_name_local(leaf, idx);
270 239894544 : namesize = xfs_attr_leaf_entsize_local(lentry->namelen,
271 239894544 : be16_to_cpu(lentry->valuelen));
272 239894544 : name_end = (char *)lentry + namesize;
273 239894544 : if (lentry->namelen == 0)
274 0 : return __this_address;
275 : } else {
276 713 : rentry = xfs_attr3_leaf_name_remote(leaf, idx);
277 713 : namesize = xfs_attr_leaf_entsize_remote(rentry->namelen);
278 713 : name_end = (char *)rentry + namesize;
279 713 : if (rentry->namelen == 0)
280 0 : return __this_address;
281 713 : if (!(ent->flags & XFS_ATTR_INCOMPLETE) &&
282 713 : rentry->valueblk == 0)
283 0 : return __this_address;
284 : }
285 :
286 239895257 : 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 13530932 : xfs_attr3_leaf_verify(
311 : struct xfs_buf *bp)
312 : {
313 13530932 : struct xfs_attr3_icleaf_hdr ichdr;
314 13530932 : struct xfs_mount *mp = bp->b_mount;
315 13530932 : struct xfs_attr_leafblock *leaf = bp->b_addr;
316 13530932 : struct xfs_attr_leaf_entry *entries;
317 13530932 : struct xfs_attr_leaf_entry *ent;
318 13530932 : char *buf_end;
319 13530932 : uint32_t end; /* must be 32bit - see below */
320 13530932 : __u32 last_hashval = 0;
321 13530932 : int i;
322 13530932 : xfs_failaddr_t fa;
323 :
324 13530932 : xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
325 :
326 13530932 : fa = xfs_da3_blkinfo_verify(bp, bp->b_addr);
327 13530959 : 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 13530949 : if (ichdr.firstused > mp->m_attr_geo->blksize)
335 0 : return __this_address;
336 27061888 : 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 13530949 : entries = xfs_attr3_leaf_entryp(bp->b_addr);
341 13530949 : if ((char *)&entries[ichdr.count] >
342 13530949 : (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 13530949 : buf_end = (char *)bp->b_addr + mp->m_attr_geo->blksize;
353 253428684 : for (i = 0, ent = entries; i < ichdr.count; ent++, i++) {
354 239897747 : fa = xfs_attr3_leaf_verify_entry(mp, buf_end, leaf, &ichdr,
355 : ent, i, &last_hashval);
356 239897735 : 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 54123745 : for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
370 40592792 : if (ichdr.freemap[i].base > mp->m_attr_geo->blksize)
371 0 : return __this_address;
372 40592763 : if (ichdr.freemap[i].base & 0x3)
373 0 : return __this_address;
374 40592774 : if (ichdr.freemap[i].size > mp->m_attr_geo->blksize)
375 0 : return __this_address;
376 40592774 : if (ichdr.freemap[i].size & 0x3)
377 0 : return __this_address;
378 :
379 : /* be care of 16 bit overflows here */
380 40592786 : end = (uint32_t)ichdr.freemap[i].base + ichdr.freemap[i].size;
381 40592793 : if (end < ichdr.freemap[i].base)
382 0 : return __this_address;
383 40592808 : if (end > mp->m_attr_geo->blksize)
384 0 : return __this_address;
385 : }
386 :
387 : return NULL;
388 : }
389 :
390 : static void
391 12240153 : xfs_attr3_leaf_write_verify(
392 : struct xfs_buf *bp)
393 : {
394 12240153 : struct xfs_mount *mp = bp->b_mount;
395 12240153 : struct xfs_buf_log_item *bip = bp->b_log_item;
396 12240153 : struct xfs_attr3_leaf_hdr *hdr3 = bp->b_addr;
397 12240153 : xfs_failaddr_t fa;
398 :
399 12240153 : fa = xfs_attr3_leaf_verify(bp);
400 12240153 : if (fa) {
401 0 : xfs_verifier_error(bp, -EFSCORRUPTED, fa);
402 0 : return;
403 : }
404 :
405 12240153 : if (!xfs_has_crc(mp))
406 : return;
407 :
408 12240153 : if (bip)
409 12240153 : hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn);
410 :
411 12240153 : 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 149232 : xfs_attr3_leaf_read_verify(
422 : struct xfs_buf *bp)
423 : {
424 149232 : struct xfs_mount *mp = bp->b_mount;
425 149232 : xfs_failaddr_t fa;
426 :
427 298464 : if (xfs_has_crc(mp) &&
428 : !xfs_buf_verify_cksum(bp, XFS_ATTR3_LEAF_CRC_OFF))
429 204 : xfs_verifier_error(bp, -EFSBADCRC, __this_address);
430 : else {
431 149028 : fa = xfs_attr3_leaf_verify(bp);
432 149028 : if (fa)
433 0 : xfs_verifier_error(bp, -EFSCORRUPTED, fa);
434 : }
435 149232 : }
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 184687282 : 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 184687282 : int err;
454 :
455 184687282 : err = xfs_da_read_buf(tp, dp, bno, 0, bpp, XFS_ATTR_FORK,
456 : &xfs_attr3_leaf_buf_ops);
457 184817806 : if (!err && tp && *bpp)
458 149136156 : xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_ATTR_LEAF_BUF);
459 184803745 : 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 4814121085 : xfs_attr_match(
476 : struct xfs_da_args *args,
477 : uint8_t namelen,
478 : unsigned char *name,
479 : int flags)
480 : {
481 :
482 4814121085 : if (args->namelen != namelen)
483 : return false;
484 9543656408 : if (memcmp(args->name, name, namelen) != 0)
485 : return false;
486 :
487 : /* Recovery ignores the INCOMPLETE flag. */
488 97677720 : if ((args->op_flags & XFS_DA_OP_RECOVERY) &&
489 44 : 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 97677690 : if (args->attr_filter !=
494 97677690 : (flags & (XFS_ATTR_NSP_ONDISK_MASK | XFS_ATTR_INCOMPLETE)))
495 207662 : return false;
496 : return true;
497 : }
498 :
499 : static int
500 21642419 : 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 21642419 : if (!args->valuelen) {
509 3948677 : args->valuelen = valuelen;
510 3948677 : return 0;
511 : }
512 :
513 : /*
514 : * No copy if the length of the existing buffer is too small
515 : */
516 17693742 : if (args->valuelen < valuelen) {
517 0 : args->valuelen = valuelen;
518 0 : return -ERANGE;
519 : }
520 :
521 17693742 : if (!args->value) {
522 146 : args->value = kvmalloc(valuelen, GFP_KERNEL | __GFP_NOLOCKDEP);
523 146 : if (!args->value)
524 : return -ENOMEM;
525 : }
526 17693742 : args->valuelen = valuelen;
527 :
528 : /* remote block xattr requires IO for copy-in */
529 17693742 : if (args->rmtblkno)
530 221 : 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 17693521 : if (!value)
539 : return -EINVAL;
540 35387042 : memcpy(args->value, value, valuelen);
541 17693521 : 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 56746302 : xfs_attr_shortform_bytesfit(
560 : struct xfs_inode *dp,
561 : int bytes)
562 : {
563 56746302 : struct xfs_mount *mp = dp->i_mount;
564 56746302 : int64_t dsize;
565 56746302 : int minforkoff;
566 56746302 : int maxforkoff;
567 56746302 : int offset;
568 :
569 : /*
570 : * Check if the new size could fit at all first:
571 : */
572 56746312 : if (bytes > XFS_LITINO(mp))
573 : return 0;
574 :
575 : /* rounded down */
576 33214369 : offset = (XFS_LITINO(mp) - bytes) >> 3;
577 :
578 33214369 : if (dp->i_df.if_format == XFS_DINODE_FMT_DEV) {
579 96 : minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
580 96 : 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 33214273 : if (bytes <= xfs_inode_attr_fork_size(dp))
594 17903039 : 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 15311234 : if (!xfs_has_attr2(mp))
602 : return 0;
603 :
604 15311234 : dsize = dp->i_df.if_bytes;
605 :
606 15311234 : switch (dp->i_df.if_format) {
607 14669459 : 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 14669459 : if (!dp->i_forkoff && dp->i_df.if_bytes >
616 3007186 : xfs_default_attroffset(dp))
617 55695 : dsize = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
618 : break;
619 51666 : 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 51666 : if (dp->i_forkoff) {
627 34354 : if (offset < dp->i_forkoff)
628 : return 0;
629 0 : return dp->i_forkoff;
630 : }
631 17312 : dsize = XFS_BMAP_BROOT_SPACE(mp, dp->i_df.if_broot);
632 17312 : 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 15276882 : minforkoff = max_t(int64_t, dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS));
640 15276882 : minforkoff = roundup(minforkoff, 8) >> 3;
641 :
642 : /* attr fork btree root can have at least this many key/ptr pairs */
643 15276882 : maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS);
644 15276882 : maxforkoff = maxforkoff >> 3; /* rounded down */
645 :
646 15276882 : if (offset >= maxforkoff)
647 : return maxforkoff;
648 14173022 : if (offset >= minforkoff)
649 10763194 : 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 31586038 : xfs_sbversion_add_attr2(
661 : struct xfs_mount *mp,
662 : struct xfs_trans *tp)
663 : {
664 31586038 : if (xfs_has_noattr2(mp))
665 : return;
666 31586038 : 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 4654285 : xfs_attr_shortform_create(
682 : struct xfs_da_args *args)
683 : {
684 4654285 : struct xfs_inode *dp = args->dp;
685 4654285 : struct xfs_ifork *ifp = &dp->i_af;
686 4654285 : struct xfs_attr_sf_hdr *hdr;
687 :
688 4654285 : trace_xfs_attr_sf_create(args);
689 :
690 4654372 : ASSERT(ifp->if_bytes == 0);
691 4654372 : if (ifp->if_format == XFS_DINODE_FMT_EXTENTS)
692 4654384 : ifp->if_format = XFS_DINODE_FMT_LOCAL;
693 4654372 : xfs_idata_realloc(dp, sizeof(*hdr), XFS_ATTR_FORK);
694 4654392 : hdr = (struct xfs_attr_sf_hdr *)ifp->if_u1.if_data;
695 4654392 : memset(hdr, 0, sizeof(*hdr));
696 4654392 : hdr->totsize = cpu_to_be16(sizeof(*hdr));
697 4654392 : xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
698 4654408 : }
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 56462196 : xfs_attr_sf_findname(
711 : struct xfs_da_args *args,
712 : struct xfs_attr_sf_entry **sfep,
713 : unsigned int *basep)
714 : {
715 56462196 : struct xfs_attr_shortform *sf;
716 56462196 : struct xfs_attr_sf_entry *sfe;
717 56462196 : unsigned int base = sizeof(struct xfs_attr_sf_hdr);
718 56462196 : int size = 0;
719 56462196 : int end;
720 56462196 : int i;
721 :
722 56462196 : sf = (struct xfs_attr_shortform *)args->dp->i_af.if_u1.if_data;
723 56462196 : sfe = &sf->list[0];
724 56462196 : end = sf->hdr.count;
725 162268243 : for (i = 0; i < end; sfe = xfs_attr_sf_nextentry(sfe),
726 105806047 : base += size, i++) {
727 123915249 : size = xfs_attr_sf_entsize(sfe);
728 123928461 : if (!xfs_attr_match(args, sfe->namelen, sfe->nameval,
729 123915249 : sfe->flags))
730 105806047 : continue;
731 : break;
732 : }
733 :
734 56475408 : if (sfep != NULL)
735 31586299 : *sfep = sfe;
736 :
737 56475408 : if (basep != NULL)
738 9041663 : *basep = base;
739 :
740 56475408 : if (i == end)
741 38352710 : 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 22546711 : xfs_attr_shortform_add(
751 : struct xfs_da_args *args,
752 : int forkoff)
753 : {
754 22546711 : struct xfs_attr_shortform *sf;
755 22546711 : struct xfs_attr_sf_entry *sfe;
756 22546711 : int offset, size;
757 22546711 : struct xfs_mount *mp;
758 22546711 : struct xfs_inode *dp;
759 22546711 : struct xfs_ifork *ifp;
760 :
761 22546711 : trace_xfs_attr_sf_add(args);
762 :
763 22547951 : dp = args->dp;
764 22547951 : mp = dp->i_mount;
765 22547951 : dp->i_forkoff = forkoff;
766 :
767 22547951 : ifp = &dp->i_af;
768 22547951 : ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
769 22547951 : sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
770 22547951 : if (xfs_attr_sf_findname(args, &sfe, NULL) == -EEXIST)
771 0 : ASSERT(0);
772 :
773 22548756 : offset = (char *)sfe - (char *)sf;
774 22548756 : size = xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
775 22548756 : xfs_idata_realloc(dp, size, XFS_ATTR_FORK);
776 22547759 : sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
777 22547759 : sfe = (struct xfs_attr_sf_entry *)((char *)sf + offset);
778 :
779 22547759 : sfe->namelen = args->namelen;
780 22547759 : sfe->valuelen = args->valuelen;
781 22547759 : sfe->flags = args->attr_filter;
782 45095518 : memcpy(sfe->nameval, args->name, args->namelen);
783 45095518 : memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
784 22547759 : sf->hdr.count++;
785 22547759 : be16_add_cpu(&sf->hdr.totsize, size);
786 22547366 : xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
787 :
788 22549378 : xfs_sbversion_add_attr2(mp, args->trans);
789 22549338 : }
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 1744765 : xfs_attr_fork_remove(
797 : struct xfs_inode *ip,
798 : struct xfs_trans *tp)
799 : {
800 1744765 : ASSERT(ip->i_af.if_nextents == 0);
801 :
802 1744765 : xfs_ifork_zap_attr(ip);
803 1744762 : ip->i_forkoff = 0;
804 1744762 : xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
805 1744799 : }
806 :
807 : /*
808 : * Remove an attribute from the shortform attribute list structure.
809 : */
810 : int
811 9037824 : xfs_attr_sf_removename(
812 : struct xfs_da_args *args)
813 : {
814 9037824 : struct xfs_attr_shortform *sf;
815 9037824 : struct xfs_attr_sf_entry *sfe;
816 9037824 : int size = 0, end, totsize;
817 9037824 : unsigned int base;
818 9037824 : struct xfs_mount *mp;
819 9037824 : struct xfs_inode *dp;
820 9037824 : int error;
821 :
822 9037824 : trace_xfs_attr_sf_remove(args);
823 :
824 9038250 : dp = args->dp;
825 9038250 : mp = dp->i_mount;
826 9038250 : sf = (struct xfs_attr_shortform *)dp->i_af.if_u1.if_data;
827 :
828 9038250 : 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 9038266 : if (error == -ENOATTR && (args->op_flags & XFS_DA_OP_RECOVERY))
836 : return 0;
837 9038260 : if (error != -EEXIST)
838 : return error;
839 9038260 : size = xfs_attr_sf_entsize(sfe);
840 :
841 : /*
842 : * Fix up the attribute fork data, covering the hole
843 : */
844 9038260 : end = base + size;
845 9038260 : totsize = be16_to_cpu(sf->hdr.totsize);
846 9038260 : if (end != totsize)
847 8514234 : memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end);
848 9038260 : sf->hdr.count--;
849 9038260 : be16_add_cpu(&sf->hdr.totsize, -size);
850 :
851 : /*
852 : * Fix up the start offset of the attribute fork
853 : */
854 9038141 : totsize -= size;
855 9038141 : if (totsize == sizeof(xfs_attr_sf_hdr_t) && xfs_has_attr2(mp) &&
856 2034706 : (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) &&
857 2004740 : !(args->op_flags & (XFS_DA_OP_ADDNAME | XFS_DA_OP_REPLACE))) {
858 704065 : xfs_attr_fork_remove(dp, args->trans);
859 : } else {
860 8334076 : xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
861 8334083 : dp->i_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
862 8334214 : ASSERT(dp->i_forkoff);
863 8334214 : 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 8334214 : xfs_trans_log_inode(args->trans, dp,
868 : XFS_ILOG_CORE | XFS_ILOG_ADATA);
869 : }
870 :
871 9038352 : xfs_sbversion_add_attr2(mp, args->trans);
872 :
873 9038352 : return 0;
874 : }
875 :
876 : /*
877 : * Look up a name in a shortform attribute list structure.
878 : */
879 : /*ARGSUSED*/
880 : int
881 19215378 : xfs_attr_shortform_lookup(xfs_da_args_t *args)
882 : {
883 19215378 : struct xfs_attr_shortform *sf;
884 19215378 : struct xfs_attr_sf_entry *sfe;
885 19215378 : int i;
886 19215378 : struct xfs_ifork *ifp;
887 :
888 19215378 : trace_xfs_attr_sf_lookup(args);
889 :
890 19216519 : ifp = &args->dp->i_af;
891 19216519 : ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
892 19216519 : sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
893 19216519 : sfe = &sf->list[0];
894 55471129 : for (i = 0; i < sf->hdr.count;
895 36254610 : sfe = xfs_attr_sf_nextentry(sfe), i++) {
896 40762563 : if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
897 40762341 : 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 20508974 : xfs_attr_shortform_getvalue(
912 : struct xfs_da_args *args)
913 : {
914 20508974 : struct xfs_attr_shortform *sf;
915 20508974 : struct xfs_attr_sf_entry *sfe;
916 20508974 : int i;
917 :
918 20508974 : ASSERT(args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL);
919 20508974 : sf = (struct xfs_attr_shortform *)args->dp->i_af.if_u1.if_data;
920 20508974 : sfe = &sf->list[0];
921 31554458 : for (i = 0; i < sf->hdr.count;
922 11045484 : sfe = xfs_attr_sf_nextentry(sfe), i++) {
923 27597642 : if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
924 27597271 : sfe->flags))
925 16552158 : return xfs_attr_copy_value(args,
926 16552158 : &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 2454671 : xfs_attr_shortform_to_leaf(
934 : struct xfs_da_args *args)
935 : {
936 2454671 : struct xfs_inode *dp;
937 2454671 : struct xfs_attr_shortform *sf;
938 2454671 : struct xfs_attr_sf_entry *sfe;
939 2454671 : struct xfs_da_args nargs;
940 2454671 : char *tmpbuffer;
941 2454671 : int error, i, size;
942 2454671 : xfs_dablk_t blkno;
943 2454671 : struct xfs_buf *bp;
944 2454671 : struct xfs_ifork *ifp;
945 :
946 2454671 : trace_xfs_attr_sf_to_leaf(args);
947 :
948 2454686 : dp = args->dp;
949 2454686 : ifp = &dp->i_af;
950 2454686 : sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
951 2454686 : size = be16_to_cpu(sf->hdr.totsize);
952 2454686 : tmpbuffer = kmem_alloc(size, 0);
953 2454638 : ASSERT(tmpbuffer != NULL);
954 4909276 : memcpy(tmpbuffer, ifp->if_u1.if_data, size);
955 2454638 : sf = (struct xfs_attr_shortform *)tmpbuffer;
956 :
957 2454638 : xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
958 2454643 : xfs_bmap_local_to_extents_empty(args->trans, dp, XFS_ATTR_FORK);
959 :
960 2454692 : bp = NULL;
961 2454692 : error = xfs_da_grow_inode(args, &blkno);
962 2454644 : if (error)
963 0 : goto out;
964 :
965 2454644 : ASSERT(blkno == 0);
966 2454644 : error = xfs_attr3_leaf_create(args, blkno, &bp);
967 2454622 : if (error)
968 0 : goto out;
969 :
970 2454622 : memset((char *)&nargs, 0, sizeof(nargs));
971 2454622 : nargs.dp = dp;
972 2454622 : nargs.geo = args->geo;
973 2454622 : nargs.total = args->total;
974 2454622 : nargs.whichfork = XFS_ATTR_FORK;
975 2454622 : nargs.trans = args->trans;
976 2454622 : nargs.op_flags = XFS_DA_OP_OKNOENT;
977 :
978 2454622 : sfe = &sf->list[0];
979 13363685 : for (i = 0; i < sf->hdr.count; i++) {
980 10909003 : nargs.name = sfe->nameval;
981 10909003 : nargs.namelen = sfe->namelen;
982 10909003 : nargs.value = &sfe->nameval[nargs.namelen];
983 10909003 : nargs.valuelen = sfe->valuelen;
984 21817812 : nargs.hashval = xfs_da_hashname(sfe->nameval,
985 10909003 : sfe->namelen);
986 10908809 : nargs.attr_filter = sfe->flags & XFS_ATTR_NSP_ONDISK_MASK;
987 10908809 : error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */
988 10908980 : ASSERT(error == -ENOATTR);
989 10908980 : error = xfs_attr3_leaf_add(bp, &nargs);
990 10909063 : ASSERT(error != -ENOSPC);
991 10909063 : if (error)
992 0 : goto out;
993 10909063 : sfe = xfs_attr_sf_nextentry(sfe);
994 : }
995 : error = 0;
996 2454682 : out:
997 2454682 : kmem_free(tmpbuffer);
998 2454683 : 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 25766254 : xfs_attr_shortform_allfit(
1007 : struct xfs_buf *bp,
1008 : struct xfs_inode *dp)
1009 : {
1010 25766254 : struct xfs_attr_leafblock *leaf;
1011 25766254 : struct xfs_attr_leaf_entry *entry;
1012 25766254 : xfs_attr_leaf_name_local_t *name_loc;
1013 25766254 : struct xfs_attr3_icleaf_hdr leafhdr;
1014 25766254 : int bytes;
1015 25766254 : int i;
1016 25766254 : struct xfs_mount *mp = bp->b_mount;
1017 :
1018 25766254 : leaf = bp->b_addr;
1019 25766254 : xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);
1020 25765053 : entry = xfs_attr3_leaf_entryp(leaf);
1021 :
1022 : bytes = sizeof(struct xfs_attr_sf_hdr);
1023 472652307 : for (i = 0; i < leafhdr.count; entry++, i++) {
1024 446887262 : if (entry->flags & XFS_ATTR_INCOMPLETE)
1025 0 : continue; /* don't copy partial entries */
1026 446887262 : if (!(entry->flags & XFS_ATTR_LOCAL))
1027 : return 0;
1028 446887262 : name_loc = xfs_attr3_leaf_name_local(leaf, i);
1029 446887262 : if (name_loc->namelen >= XFS_ATTR_SF_ENTSIZE_MAX)
1030 : return 0;
1031 446887262 : if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX)
1032 : return 0;
1033 446887254 : bytes += xfs_attr_sf_entsize_byname(name_loc->namelen,
1034 0 : be16_to_cpu(name_loc->valuelen));
1035 : }
1036 25765045 : if (xfs_has_attr2(dp->i_mount) &&
1037 25765045 : (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) &&
1038 : (bytes == sizeof(struct xfs_attr_sf_hdr)))
1039 : return -1;
1040 25764888 : return xfs_attr_shortform_bytesfit(dp, bytes);
1041 : }
1042 :
1043 : /* Verify the consistency of an inline attribute fork. */
1044 : xfs_failaddr_t
1045 55161665 : xfs_attr_shortform_verify(
1046 : struct xfs_inode *ip)
1047 : {
1048 55161665 : struct xfs_attr_shortform *sfp;
1049 55161665 : struct xfs_attr_sf_entry *sfep;
1050 55161665 : struct xfs_attr_sf_entry *next_sfep;
1051 55161665 : char *endp;
1052 55161665 : struct xfs_ifork *ifp;
1053 55161665 : int i;
1054 55161665 : int64_t size;
1055 :
1056 55161665 : ASSERT(ip->i_af.if_format == XFS_DINODE_FMT_LOCAL);
1057 55161665 : ifp = xfs_ifork_ptr(ip, XFS_ATTR_FORK);
1058 55161665 : sfp = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
1059 55161665 : size = ifp->if_bytes;
1060 :
1061 : /*
1062 : * Give up if the attribute is way too short.
1063 : */
1064 55161665 : if (size < sizeof(struct xfs_attr_sf_hdr))
1065 0 : return __this_address;
1066 :
1067 55161665 : endp = (char *)sfp + size;
1068 :
1069 : /* Check all reported entries */
1070 55161665 : sfep = &sfp->list[0];
1071 133065579 : 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 77903698 : if (((char *)sfep + sizeof(*sfep)) >= endp)
1080 0 : return __this_address;
1081 :
1082 : /* Don't allow names with known bad length. */
1083 77903698 : 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 77903698 : next_sfep = xfs_attr_sf_nextentry(sfep);
1092 77903698 : 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 77903698 : 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 155807612 : if (hweight8(sfep->flags & XFS_ATTR_NSP_ONDISK_MASK) > 1)
1109 0 : return __this_address;
1110 :
1111 77903914 : sfep = next_sfep;
1112 : }
1113 55161881 : 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 1243331 : xfs_attr3_leaf_to_shortform(
1124 : struct xfs_buf *bp,
1125 : struct xfs_da_args *args,
1126 : int forkoff)
1127 : {
1128 1243331 : struct xfs_attr_leafblock *leaf;
1129 1243331 : struct xfs_attr3_icleaf_hdr ichdr;
1130 1243331 : struct xfs_attr_leaf_entry *entry;
1131 1243331 : struct xfs_attr_leaf_name_local *name_loc;
1132 1243331 : struct xfs_da_args nargs;
1133 1243331 : struct xfs_inode *dp = args->dp;
1134 1243331 : char *tmpbuffer;
1135 1243331 : int error;
1136 1243331 : int i;
1137 :
1138 1243331 : trace_xfs_attr_leaf_to_sf(args);
1139 :
1140 1243375 : tmpbuffer = kmem_alloc(args->geo->blksize, 0);
1141 1243352 : if (!tmpbuffer)
1142 : return -ENOMEM;
1143 :
1144 2486704 : memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
1145 :
1146 1243352 : leaf = (xfs_attr_leafblock_t *)tmpbuffer;
1147 1243352 : xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
1148 1243368 : entry = xfs_attr3_leaf_entryp(leaf);
1149 :
1150 : /* XXX (dgc): buffer is about to be marked stale - why zero it? */
1151 1243368 : memset(bp->b_addr, 0, args->geo->blksize);
1152 :
1153 : /*
1154 : * Clean out the prior contents of the attribute list.
1155 : */
1156 1243368 : error = xfs_da_shrink_inode(args, 0, bp);
1157 1243365 : if (error)
1158 0 : goto out;
1159 :
1160 1243365 : 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 157 : if (!(args->op_flags & XFS_DA_OP_REPLACE)) {
1168 157 : ASSERT(xfs_has_attr2(dp->i_mount));
1169 157 : ASSERT(dp->i_df.if_format != XFS_DINODE_FMT_BTREE);
1170 157 : xfs_attr_fork_remove(dp, args->trans);
1171 : }
1172 157 : goto out;
1173 : }
1174 :
1175 1243208 : xfs_attr_shortform_create(args);
1176 :
1177 : /*
1178 : * Copy the attributes
1179 : */
1180 1243208 : memset((char *)&nargs, 0, sizeof(nargs));
1181 1243208 : nargs.geo = args->geo;
1182 1243208 : nargs.dp = dp;
1183 1243208 : nargs.total = args->total;
1184 1243208 : nargs.whichfork = XFS_ATTR_FORK;
1185 1243208 : nargs.trans = args->trans;
1186 1243208 : nargs.op_flags = XFS_DA_OP_OKNOENT;
1187 :
1188 7030401 : for (i = 0; i < ichdr.count; entry++, i++) {
1189 5787182 : if (entry->flags & XFS_ATTR_INCOMPLETE)
1190 0 : continue; /* don't copy partial entries */
1191 5787182 : if (!entry->nameidx)
1192 0 : continue;
1193 5787182 : ASSERT(entry->flags & XFS_ATTR_LOCAL);
1194 5787182 : name_loc = xfs_attr3_leaf_name_local(leaf, i);
1195 5787182 : nargs.name = name_loc->nameval;
1196 5787182 : nargs.namelen = name_loc->namelen;
1197 5787182 : nargs.value = &name_loc->nameval[nargs.namelen];
1198 5787182 : nargs.valuelen = be16_to_cpu(name_loc->valuelen);
1199 5787182 : nargs.hashval = be32_to_cpu(entry->hashval);
1200 5787182 : nargs.attr_filter = entry->flags & XFS_ATTR_NSP_ONDISK_MASK;
1201 5787182 : xfs_attr_shortform_add(&nargs, forkoff);
1202 : }
1203 : error = 0;
1204 :
1205 1243376 : out:
1206 1243376 : kmem_free(tmpbuffer);
1207 1243376 : return error;
1208 : }
1209 :
1210 : /*
1211 : * Convert from using a single leaf to a root node and a leaf.
1212 : */
1213 : int
1214 22154 : xfs_attr3_leaf_to_node(
1215 : struct xfs_da_args *args)
1216 : {
1217 22154 : struct xfs_attr_leafblock *leaf;
1218 22154 : struct xfs_attr3_icleaf_hdr icleafhdr;
1219 22154 : struct xfs_attr_leaf_entry *entries;
1220 22154 : struct xfs_da3_icnode_hdr icnodehdr;
1221 22154 : struct xfs_da_intnode *node;
1222 22154 : struct xfs_inode *dp = args->dp;
1223 22154 : struct xfs_mount *mp = dp->i_mount;
1224 22154 : struct xfs_buf *bp1 = NULL;
1225 22154 : struct xfs_buf *bp2 = NULL;
1226 22154 : xfs_dablk_t blkno;
1227 22154 : int error;
1228 :
1229 22154 : trace_xfs_attr_leaf_to_node(args);
1230 :
1231 22154 : if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_ATTR_LEAF_TO_NODE)) {
1232 2 : error = -EIO;
1233 2 : goto out;
1234 : }
1235 :
1236 22152 : error = xfs_da_grow_inode(args, &blkno);
1237 22152 : if (error)
1238 0 : goto out;
1239 22152 : error = xfs_attr3_leaf_read(args->trans, dp, 0, &bp1);
1240 22152 : if (error)
1241 0 : goto out;
1242 :
1243 22152 : error = xfs_da_get_buf(args->trans, dp, blkno, &bp2, XFS_ATTR_FORK);
1244 22152 : if (error)
1245 0 : goto out;
1246 :
1247 : /* copy leaf to new buffer, update identifiers */
1248 22152 : xfs_trans_buf_set_type(args->trans, bp2, XFS_BLFT_ATTR_LEAF_BUF);
1249 22152 : bp2->b_ops = bp1->b_ops;
1250 44304 : memcpy(bp2->b_addr, bp1->b_addr, args->geo->blksize);
1251 22152 : if (xfs_has_crc(mp)) {
1252 22152 : struct xfs_da3_blkinfo *hdr3 = bp2->b_addr;
1253 22152 : hdr3->blkno = cpu_to_be64(xfs_buf_daddr(bp2));
1254 : }
1255 22152 : xfs_trans_log_buf(args->trans, bp2, 0, args->geo->blksize - 1);
1256 :
1257 : /*
1258 : * Set up the new root node.
1259 : */
1260 22152 : error = xfs_da3_node_create(args, 0, 1, &bp1, XFS_ATTR_FORK);
1261 22152 : if (error)
1262 0 : goto out;
1263 22152 : node = bp1->b_addr;
1264 22152 : xfs_da3_node_hdr_from_disk(mp, &icnodehdr, node);
1265 :
1266 22152 : leaf = bp2->b_addr;
1267 22152 : xfs_attr3_leaf_hdr_from_disk(args->geo, &icleafhdr, leaf);
1268 22152 : entries = xfs_attr3_leaf_entryp(leaf);
1269 :
1270 : /* both on-disk, don't endian-flip twice */
1271 22152 : icnodehdr.btree[0].hashval = entries[icleafhdr.count - 1].hashval;
1272 22152 : icnodehdr.btree[0].before = cpu_to_be32(blkno);
1273 22152 : icnodehdr.count = 1;
1274 22152 : xfs_da3_node_hdr_to_disk(dp->i_mount, node, &icnodehdr);
1275 22152 : xfs_trans_log_buf(args->trans, bp1, 0, args->geo->blksize - 1);
1276 22152 : error = 0;
1277 22154 : out:
1278 22154 : 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 2491733 : xfs_attr3_leaf_create(
1291 : struct xfs_da_args *args,
1292 : xfs_dablk_t blkno,
1293 : struct xfs_buf **bpp)
1294 : {
1295 2491733 : struct xfs_attr_leafblock *leaf;
1296 2491733 : struct xfs_attr3_icleaf_hdr ichdr;
1297 2491733 : struct xfs_inode *dp = args->dp;
1298 2491733 : struct xfs_mount *mp = dp->i_mount;
1299 2491733 : struct xfs_buf *bp;
1300 2491733 : int error;
1301 :
1302 2491733 : trace_xfs_attr_leaf_create(args);
1303 :
1304 2491786 : error = xfs_da_get_buf(args->trans, args->dp, blkno, &bp,
1305 : XFS_ATTR_FORK);
1306 2491822 : if (error)
1307 : return error;
1308 2491822 : bp->b_ops = &xfs_attr3_leaf_buf_ops;
1309 2491822 : xfs_trans_buf_set_type(args->trans, bp, XFS_BLFT_ATTR_LEAF_BUF);
1310 2491816 : leaf = bp->b_addr;
1311 2491816 : memset(leaf, 0, args->geo->blksize);
1312 :
1313 2491816 : memset(&ichdr, 0, sizeof(ichdr));
1314 2491816 : ichdr.firstused = args->geo->blksize;
1315 :
1316 2491816 : if (xfs_has_crc(mp)) {
1317 2491816 : struct xfs_da3_blkinfo *hdr3 = bp->b_addr;
1318 :
1319 2491816 : ichdr.magic = XFS_ATTR3_LEAF_MAGIC;
1320 :
1321 2491816 : hdr3->blkno = cpu_to_be64(xfs_buf_daddr(bp));
1322 2491816 : hdr3->owner = cpu_to_be64(dp->i_ino);
1323 2491816 : uuid_copy(&hdr3->uuid, &mp->m_sb.sb_meta_uuid);
1324 :
1325 2491819 : 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 2491819 : ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base;
1331 :
1332 2491819 : xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr);
1333 2491821 : xfs_trans_log_buf(args->trans, bp, 0, args->geo->blksize - 1);
1334 :
1335 2491813 : *bpp = bp;
1336 2491813 : return 0;
1337 : }
1338 :
1339 : /*
1340 : * Split the leaf node, rebalance, then add the new entry.
1341 : */
1342 : int
1343 37129 : 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 37129 : xfs_dablk_t blkno;
1349 37129 : int error;
1350 :
1351 37129 : trace_xfs_attr_leaf_split(state->args);
1352 :
1353 : /*
1354 : * Allocate space for a new leaf node.
1355 : */
1356 37129 : ASSERT(oldblk->magic == XFS_ATTR_LEAF_MAGIC);
1357 37129 : error = xfs_da_grow_inode(state->args, &blkno);
1358 37129 : if (error)
1359 : return error;
1360 37129 : error = xfs_attr3_leaf_create(state->args, blkno, &newblk->bp);
1361 37129 : if (error)
1362 : return error;
1363 37129 : newblk->blkno = blkno;
1364 37129 : 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 37129 : xfs_attr3_leaf_rebalance(state, oldblk, newblk);
1371 37129 : error = xfs_da3_blk_link(state, oldblk, newblk);
1372 37129 : 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 37129 : if (state->inleaf) {
1383 6322 : trace_xfs_attr_leaf_add_old(state->args);
1384 6322 : error = xfs_attr3_leaf_add(oldblk->bp, state->args);
1385 : } else {
1386 30807 : trace_xfs_attr_leaf_add_new(state->args);
1387 30807 : 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 37129 : oldblk->hashval = xfs_attr_leaf_lasthash(oldblk->bp, NULL);
1394 37129 : newblk->hashval = xfs_attr_leaf_lasthash(newblk->bp, NULL);
1395 37129 : return error;
1396 : }
1397 :
1398 : /*
1399 : * Add a name to the leaf attribute list structure.
1400 : */
1401 : int
1402 54296081 : xfs_attr3_leaf_add(
1403 : struct xfs_buf *bp,
1404 : struct xfs_da_args *args)
1405 : {
1406 54296081 : struct xfs_attr_leafblock *leaf;
1407 54296081 : struct xfs_attr3_icleaf_hdr ichdr;
1408 54296081 : int tablesize;
1409 54296081 : int entsize;
1410 54296081 : int sum;
1411 54296081 : int tmp;
1412 54296081 : int i;
1413 :
1414 54296081 : trace_xfs_attr_leaf_add(args);
1415 :
1416 54307578 : leaf = bp->b_addr;
1417 54307578 : xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
1418 54300387 : ASSERT(args->index >= 0 && args->index <= ichdr.count);
1419 54300387 : 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 54309029 : tablesize = (ichdr.count + 1) * sizeof(xfs_attr_leaf_entry_t)
1426 54309029 : + xfs_attr3_leaf_hdr_size(leaf);
1427 131349146 : for (sum = 0, i = XFS_ATTR_LEAF_MAPSIZE - 1; i >= 0; i--) {
1428 131132778 : if (tablesize > ichdr.firstused) {
1429 51531 : sum += ichdr.freemap[i].size;
1430 51531 : continue;
1431 : }
1432 131081247 : if (!ichdr.freemap[i].size)
1433 41314991 : continue; /* no space in this map */
1434 89759115 : tmp = entsize;
1435 89759115 : if (ichdr.freemap[i].base < ichdr.firstused)
1436 34589492 : tmp += sizeof(xfs_attr_leaf_entry_t);
1437 89763384 : if (ichdr.freemap[i].size >= tmp) {
1438 54091758 : tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, i);
1439 54091446 : goto out_log_hdr;
1440 : }
1441 35673841 : 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 216368 : 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 173521 : 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 173521 : if (ichdr.freemap[0].size < (entsize + sizeof(xfs_attr_leaf_entry_t))) {
1463 16438 : tmp = -ENOSPC;
1464 16438 : goto out_log_hdr;
1465 : }
1466 :
1467 157083 : tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, 0);
1468 :
1469 54264967 : out_log_hdr:
1470 54264967 : xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr);
1471 54267868 : xfs_trans_log_buf(args->trans, bp,
1472 54267868 : XFS_DA_LOGRANGE(leaf, &leaf->hdr,
1473 : xfs_attr3_leaf_hdr_size(leaf)));
1474 54267868 : return tmp;
1475 : }
1476 :
1477 : /*
1478 : * Add a name to a leaf attribute list structure.
1479 : */
1480 : STATIC int
1481 54237912 : 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 54237912 : struct xfs_attr_leafblock *leaf;
1488 54237912 : struct xfs_attr_leaf_entry *entry;
1489 54237912 : struct xfs_attr_leaf_name_local *name_loc;
1490 54237912 : struct xfs_attr_leaf_name_remote *name_rmt;
1491 54237912 : struct xfs_mount *mp;
1492 54237912 : int tmp;
1493 54237912 : int i;
1494 :
1495 54237912 : trace_xfs_attr_leaf_add_work(args);
1496 :
1497 54250055 : leaf = bp->b_addr;
1498 54250055 : ASSERT(mapindex >= 0 && mapindex < XFS_ATTR_LEAF_MAPSIZE);
1499 54250055 : 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 54250055 : entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
1505 54250055 : if (args->index < ichdr->count) {
1506 19075132 : tmp = ichdr->count - args->index;
1507 19075132 : tmp *= sizeof(xfs_attr_leaf_entry_t);
1508 38150264 : memmove(entry + 1, entry, tmp);
1509 19075132 : xfs_trans_log_buf(args->trans, bp,
1510 19075132 : XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry)));
1511 : }
1512 54250072 : ichdr->count++;
1513 :
1514 : /*
1515 : * Allocate space for the new string (at the end of the run).
1516 : */
1517 54250072 : mp = args->trans->t_mountp;
1518 54250072 : ASSERT(ichdr->freemap[mapindex].base < args->geo->blksize);
1519 54245412 : ASSERT((ichdr->freemap[mapindex].base & 0x3) == 0);
1520 54246578 : ASSERT(ichdr->freemap[mapindex].size >=
1521 : xfs_attr_leaf_newentsize(args, NULL));
1522 54248201 : ASSERT(ichdr->freemap[mapindex].size < args->geo->blksize);
1523 54245649 : ASSERT((ichdr->freemap[mapindex].size & 0x3) == 0);
1524 :
1525 54246692 : ichdr->freemap[mapindex].size -= xfs_attr_leaf_newentsize(args, &tmp);
1526 :
1527 54246876 : entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base +
1528 : ichdr->freemap[mapindex].size);
1529 54248206 : entry->hashval = cpu_to_be32(args->hashval);
1530 54248206 : entry->flags = args->attr_filter;
1531 54248206 : if (tmp)
1532 54246911 : entry->flags |= XFS_ATTR_LOCAL;
1533 54248206 : if (args->op_flags & XFS_DA_OP_REPLACE) {
1534 10271268 : if (!(args->op_flags & XFS_DA_OP_LOGGED))
1535 10271322 : entry->flags |= XFS_ATTR_INCOMPLETE;
1536 10271268 : if ((args->blkno2 == args->blkno) &&
1537 10271106 : (args->index2 <= args->index)) {
1538 10270953 : args->index2++;
1539 : }
1540 : }
1541 54248206 : xfs_trans_log_buf(args->trans, bp,
1542 54248206 : XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
1543 153735886 : ASSERT((args->index == 0) ||
1544 : (be32_to_cpu(entry->hashval) >= be32_to_cpu((entry-1)->hashval)));
1545 92394986 : 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 54245022 : if (entry->flags & XFS_ATTR_LOCAL) {
1556 54244570 : name_loc = xfs_attr3_leaf_name_local(leaf, args->index);
1557 54244570 : name_loc->namelen = args->namelen;
1558 54244570 : name_loc->valuelen = cpu_to_be16(args->valuelen);
1559 108489140 : memcpy((char *)name_loc->nameval, args->name, args->namelen);
1560 108489140 : memcpy((char *)&name_loc->nameval[args->namelen], args->value,
1561 : be16_to_cpu(name_loc->valuelen));
1562 : } else {
1563 452 : name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
1564 452 : name_rmt->namelen = args->namelen;
1565 904 : memcpy((char *)name_rmt->name, args->name, args->namelen);
1566 452 : entry->flags |= XFS_ATTR_INCOMPLETE;
1567 : /* just in case */
1568 452 : name_rmt->valuelen = 0;
1569 452 : name_rmt->valueblk = 0;
1570 452 : args->rmtblkno = 1;
1571 452 : args->rmtblkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen);
1572 452 : args->rmtvaluelen = args->valuelen;
1573 : }
1574 54245022 : xfs_trans_log_buf(args->trans, bp,
1575 54245022 : 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 54239396 : if (be16_to_cpu(entry->nameidx) < ichdr->firstused)
1582 34540189 : ichdr->firstused = be16_to_cpu(entry->nameidx);
1583 :
1584 108487994 : ASSERT(ichdr->firstused >= ichdr->count * sizeof(xfs_attr_leaf_entry_t)
1585 : + xfs_attr3_leaf_hdr_size(leaf));
1586 108478792 : tmp = (ichdr->count - 1) * sizeof(xfs_attr_leaf_entry_t)
1587 54239396 : + xfs_attr3_leaf_hdr_size(leaf);
1588 :
1589 216946529 : for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
1590 162697421 : if (ichdr->freemap[i].base == tmp) {
1591 54229272 : ichdr->freemap[i].base += sizeof(xfs_attr_leaf_entry_t);
1592 54228781 : ichdr->freemap[i].size -=
1593 54227559 : min_t(uint16_t, ichdr->freemap[i].size,
1594 : sizeof(xfs_attr_leaf_entry_t));
1595 : }
1596 : }
1597 54249108 : ichdr->usedbytes += xfs_attr_leaf_entsize(leaf, args->index);
1598 54249108 : 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 173519 : 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 173519 : struct xfs_attr_leafblock *leaf_src;
1611 173519 : struct xfs_attr_leafblock *leaf_dst;
1612 173519 : struct xfs_attr3_icleaf_hdr ichdr_src;
1613 173519 : struct xfs_trans *trans = args->trans;
1614 173519 : char *tmpbuffer;
1615 :
1616 173519 : trace_xfs_attr_leaf_compact(args);
1617 :
1618 173521 : tmpbuffer = kmem_alloc(args->geo->blksize, 0);
1619 347042 : memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
1620 173521 : memset(bp->b_addr, 0, args->geo->blksize);
1621 173521 : leaf_src = (xfs_attr_leafblock_t *)tmpbuffer;
1622 173521 : 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 520563 : memcpy(bp->b_addr, tmpbuffer, xfs_attr3_leaf_hdr_size(leaf_src));
1630 :
1631 : /* Initialise the incore headers */
1632 173521 : ichdr_src = *ichdr_dst; /* struct copy */
1633 173521 : ichdr_dst->firstused = args->geo->blksize;
1634 173521 : ichdr_dst->usedbytes = 0;
1635 173521 : ichdr_dst->count = 0;
1636 173521 : ichdr_dst->holes = 0;
1637 173521 : ichdr_dst->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_src);
1638 173521 : 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 173521 : 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 173521 : xfs_attr3_leaf_moveents(args, leaf_src, &ichdr_src, 0,
1649 173521 : 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 173520 : xfs_trans_log_buf(trans, bp, 0, args->geo->blksize - 1);
1655 :
1656 173521 : kmem_free(tmpbuffer);
1657 173521 : }
1658 :
1659 : /*
1660 : * Compare two leaf blocks "order".
1661 : * Return 0 unless leaf2 should go before leaf1.
1662 : */
1663 : static int
1664 74657 : 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 74657 : struct xfs_attr_leaf_entry *entries1;
1671 74657 : struct xfs_attr_leaf_entry *entries2;
1672 :
1673 74657 : entries1 = xfs_attr3_leaf_entryp(leaf1_bp->b_addr);
1674 74657 : entries2 = xfs_attr3_leaf_entryp(leaf2_bp->b_addr);
1675 112185 : if (leaf1hdr->count > 0 && leaf2hdr->count > 0 &&
1676 37528 : ((be32_to_cpu(entries2[0].hashval) <
1677 75021 : be32_to_cpu(entries1[0].hashval)) ||
1678 37493 : (be32_to_cpu(entries2[leaf2hdr->count - 1].hashval) <
1679 37493 : be32_to_cpu(entries1[leaf1hdr->count - 1].hashval)))) {
1680 35 : return 1;
1681 : }
1682 : return 0;
1683 : }
1684 :
1685 : int
1686 37129 : xfs_attr_leaf_order(
1687 : struct xfs_buf *leaf1_bp,
1688 : struct xfs_buf *leaf2_bp)
1689 : {
1690 37129 : struct xfs_attr3_icleaf_hdr ichdr1;
1691 37129 : struct xfs_attr3_icleaf_hdr ichdr2;
1692 37129 : struct xfs_mount *mp = leaf1_bp->b_mount;
1693 :
1694 37129 : xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr1, leaf1_bp->b_addr);
1695 37129 : xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr2, leaf2_bp->b_addr);
1696 37129 : 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 37129 : 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 37129 : struct xfs_da_args *args;
1718 37129 : struct xfs_attr_leafblock *leaf1;
1719 37129 : struct xfs_attr_leafblock *leaf2;
1720 37129 : struct xfs_attr3_icleaf_hdr ichdr1;
1721 37129 : struct xfs_attr3_icleaf_hdr ichdr2;
1722 37129 : struct xfs_attr_leaf_entry *entries1;
1723 37129 : struct xfs_attr_leaf_entry *entries2;
1724 37129 : int count;
1725 37129 : int totallen;
1726 37129 : int max;
1727 37129 : int space;
1728 37129 : int swap;
1729 :
1730 : /*
1731 : * Set up environment.
1732 : */
1733 37129 : ASSERT(blk1->magic == XFS_ATTR_LEAF_MAGIC);
1734 37129 : ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC);
1735 37129 : leaf1 = blk1->bp->b_addr;
1736 37129 : leaf2 = blk2->bp->b_addr;
1737 37129 : xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr1, leaf1);
1738 37129 : xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr2, leaf2);
1739 37129 : ASSERT(ichdr2.count == 0);
1740 37129 : args = state->args;
1741 :
1742 37129 : 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 37129 : swap = 0;
1751 37129 : 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 37129 : state->inleaf = xfs_attr3_leaf_figure_balance(state, blk1, &ichdr1,
1771 : blk2, &ichdr2,
1772 : &count, &totallen);
1773 37129 : if (swap)
1774 0 : state->inleaf = !state->inleaf;
1775 :
1776 : /*
1777 : * Move any entries required from leaf to leaf:
1778 : */
1779 37129 : if (count < ichdr1.count) {
1780 : /*
1781 : * Figure the total bytes to be added to the destination leaf.
1782 : */
1783 : /* number entries being moved */
1784 37129 : count = ichdr1.count - count;
1785 37129 : space = ichdr1.usedbytes - totallen;
1786 37129 : space += count * sizeof(xfs_attr_leaf_entry_t);
1787 :
1788 : /*
1789 : * leaf2 is the destination, compact it if it looks tight.
1790 : */
1791 37129 : max = ichdr2.firstused - xfs_attr3_leaf_hdr_size(leaf1);
1792 37129 : max -= ichdr2.count * sizeof(xfs_attr_leaf_entry_t);
1793 37129 : 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 37129 : xfs_attr3_leaf_moveents(args, leaf1, &ichdr1,
1800 37129 : 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 37129 : xfs_attr3_leaf_hdr_to_disk(state->args->geo, leaf1, &ichdr1);
1833 37129 : xfs_attr3_leaf_hdr_to_disk(state->args->geo, leaf2, &ichdr2);
1834 37129 : xfs_trans_log_buf(args->trans, blk1->bp, 0, args->geo->blksize - 1);
1835 37129 : 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 37129 : entries1 = xfs_attr3_leaf_entryp(leaf1);
1841 37129 : entries2 = xfs_attr3_leaf_entryp(leaf2);
1842 37129 : blk1->hashval = be32_to_cpu(entries1[ichdr1.count - 1].hashval);
1843 37129 : 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 37129 : if (blk1->index > ichdr1.count) {
1858 30577 : ASSERT(state->inleaf == 0);
1859 30577 : blk2->index = blk1->index - ichdr1.count;
1860 30577 : args->index = args->index2 = blk2->index;
1861 30577 : args->blkno = args->blkno2 = blk2->blkno;
1862 6552 : } else if (blk1->index == ichdr1.count) {
1863 436 : if (state->inleaf) {
1864 206 : args->index = blk1->index;
1865 206 : args->blkno = blk1->blkno;
1866 206 : args->index2 = 0;
1867 206 : 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 230 : blk2->index = blk1->index - ichdr1.count;
1875 230 : args->index = blk2->index;
1876 230 : args->blkno = blk2->blkno;
1877 230 : 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 230 : args->index2 = blk2->index;
1884 230 : args->blkno2 = blk2->blkno;
1885 : }
1886 : }
1887 : } else {
1888 6116 : ASSERT(state->inleaf == 1);
1889 6116 : args->index = args->index2 = blk1->index;
1890 6116 : args->blkno = args->blkno2 = blk1->blkno;
1891 : }
1892 37129 : }
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 37129 : 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 37129 : struct xfs_attr_leafblock *leaf1 = blk1->bp->b_addr;
1912 37129 : struct xfs_attr_leafblock *leaf2 = blk2->bp->b_addr;
1913 37129 : struct xfs_attr_leaf_entry *entry;
1914 37129 : int count;
1915 37129 : int max;
1916 37129 : int index;
1917 37129 : int totallen = 0;
1918 37129 : int half;
1919 37129 : int lastdelta;
1920 37129 : int foundit = 0;
1921 37129 : 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 37129 : max = ichdr1->count + ichdr2->count;
1928 37129 : half = (max + 1) * sizeof(*entry);
1929 74258 : half += ichdr1->usedbytes + ichdr2->usedbytes +
1930 37129 : xfs_attr_leaf_newentsize(state->args, NULL);
1931 37129 : half /= 2;
1932 37129 : lastdelta = state->args->geo->blksize;
1933 37129 : entry = xfs_attr3_leaf_entryp(leaf1);
1934 938017 : 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 938017 : if (count == blk1->index) {
1941 13104 : tmp = totallen + sizeof(*entry) +
1942 6552 : xfs_attr_leaf_newentsize(state->args, NULL);
1943 6552 : 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 937787 : 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 937787 : tmp = totallen + sizeof(*entry) + xfs_attr_leaf_entsize(leaf1,
1963 : index);
1964 937787 : if (XFS_ATTR_ABS(half - tmp) > lastdelta)
1965 : break;
1966 900888 : lastdelta = XFS_ATTR_ABS(half - tmp);
1967 900888 : 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 37129 : totallen -= count * sizeof(*entry);
1976 37129 : if (foundit) {
1977 12644 : totallen -= sizeof(*entry) +
1978 6322 : xfs_attr_leaf_newentsize(state->args, NULL);
1979 : }
1980 :
1981 37129 : *countarg = count;
1982 37129 : *usedbytesarg = totallen;
1983 37129 : 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 536854 : xfs_attr3_leaf_toosmall(
2003 : struct xfs_da_state *state,
2004 : int *action)
2005 : {
2006 536854 : struct xfs_attr_leafblock *leaf;
2007 536854 : struct xfs_da_state_blk *blk;
2008 536854 : struct xfs_attr3_icleaf_hdr ichdr;
2009 536854 : struct xfs_buf *bp;
2010 536854 : xfs_dablk_t blkno;
2011 536854 : int bytes;
2012 536854 : int forward;
2013 536854 : int error;
2014 536854 : int retval;
2015 536854 : int i;
2016 :
2017 536854 : 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 536857 : blk = &state->path.blk[ state->path.active-1 ];
2025 536857 : leaf = blk->bp->b_addr;
2026 536857 : xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr, leaf);
2027 536857 : bytes = xfs_attr3_leaf_hdr_size(leaf) +
2028 536857 : ichdr.count * sizeof(xfs_attr_leaf_entry_t) +
2029 536857 : ichdr.usedbytes;
2030 536857 : if (bytes > (state->args->geo->blksize >> 1)) {
2031 356269 : *action = 0; /* blk over 50%, don't try to join */
2032 356269 : 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 180588 : 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 180588 : forward = ichdr.forw < ichdr.back;
2069 541162 : for (i = 0; i < 2; forward = !forward, i++) {
2070 360975 : struct xfs_attr3_icleaf_hdr ichdr2;
2071 360975 : if (forward)
2072 : blkno = ichdr.forw;
2073 : else
2074 180574 : blkno = ichdr.back;
2075 360975 : if (blkno == 0)
2076 164639 : continue;
2077 196336 : error = xfs_attr3_leaf_read(state->args->trans, state->args->dp,
2078 : blkno, &bp);
2079 196336 : if (error)
2080 2 : return error;
2081 :
2082 196334 : xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr2, bp->b_addr);
2083 :
2084 392668 : bytes = state->args->geo->blksize -
2085 196334 : (state->args->geo->blksize >> 2) -
2086 196334 : ichdr.usedbytes - ichdr2.usedbytes -
2087 196334 : ((ichdr.count + ichdr2.count) *
2088 196334 : sizeof(xfs_attr_leaf_entry_t)) -
2089 196334 : xfs_attr3_leaf_hdr_size(leaf);
2090 :
2091 196334 : xfs_trans_brelse(state->args->trans, bp);
2092 196334 : if (bytes >= 0)
2093 : break; /* fits with at least 25% to spare */
2094 : }
2095 180586 : if (i >= 2) {
2096 180187 : *action = 0;
2097 180187 : 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 798 : memcpy(&state->altpath, &state->path, sizeof(state->path));
2105 399 : if (blkno < blk->blkno) {
2106 211 : error = xfs_da3_path_shift(state, &state->altpath, forward,
2107 : 0, &retval);
2108 : } else {
2109 188 : error = xfs_da3_path_shift(state, &state->path, forward,
2110 : 0, &retval);
2111 : }
2112 399 : if (error)
2113 : return error;
2114 399 : if (retval) {
2115 0 : *action = 0;
2116 : } else {
2117 399 : *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 26302608 : xfs_attr3_leaf_remove(
2130 : struct xfs_buf *bp,
2131 : struct xfs_da_args *args)
2132 : {
2133 26302608 : struct xfs_attr_leafblock *leaf;
2134 26302608 : struct xfs_attr3_icleaf_hdr ichdr;
2135 26302608 : struct xfs_attr_leaf_entry *entry;
2136 26302608 : int before;
2137 26302608 : int after;
2138 26302608 : int smallest;
2139 26302608 : int entsize;
2140 26302608 : int tablesize;
2141 26302608 : int tmp;
2142 26302608 : int i;
2143 :
2144 26302608 : trace_xfs_attr_leaf_remove(args);
2145 :
2146 26303563 : leaf = bp->b_addr;
2147 26303563 : xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
2148 :
2149 26303582 : ASSERT(ichdr.count > 0 && ichdr.count < args->geo->blksize / 8);
2150 26303582 : ASSERT(args->index >= 0 && args->index < ichdr.count);
2151 52603378 : ASSERT(ichdr.firstused >= ichdr.count * sizeof(*entry) +
2152 : xfs_attr3_leaf_hdr_size(leaf));
2153 :
2154 26303582 : entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
2155 :
2156 26303582 : ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused);
2157 26303582 : 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 26303582 : tablesize = ichdr.count * sizeof(xfs_attr_leaf_entry_t)
2166 26303582 : + xfs_attr3_leaf_hdr_size(leaf);
2167 26303582 : tmp = ichdr.freemap[0].size;
2168 26303582 : before = after = -1;
2169 26303582 : smallest = XFS_ATTR_LEAF_MAPSIZE - 1;
2170 26303582 : entsize = xfs_attr_leaf_entsize(leaf, args->index);
2171 105210289 : for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
2172 78906843 : ASSERT(ichdr.freemap[i].base < args->geo->blksize);
2173 78906838 : ASSERT(ichdr.freemap[i].size < args->geo->blksize);
2174 78910302 : if (ichdr.freemap[i].base == tablesize) {
2175 26261659 : ichdr.freemap[i].base -= sizeof(xfs_attr_leaf_entry_t);
2176 26261916 : ichdr.freemap[i].size += sizeof(xfs_attr_leaf_entry_t);
2177 : }
2178 :
2179 157815898 : if (ichdr.freemap[i].base + ichdr.freemap[i].size ==
2180 78906652 : be16_to_cpu(entry->nameidx)) {
2181 : before = i;
2182 74809107 : } else if (ichdr.freemap[i].base ==
2183 74808604 : (be16_to_cpu(entry->nameidx) + entsize)) {
2184 : after = i;
2185 72177460 : } else if (ichdr.freemap[i].size < tmp) {
2186 37444503 : tmp = ichdr.freemap[i].size;
2187 37444503 : smallest = i;
2188 : }
2189 : }
2190 :
2191 : /*
2192 : * Coalesce adjacent freemap regions,
2193 : * or replace the smallest region.
2194 : */
2195 26303446 : if ((before >= 0) || (after >= 0)) {
2196 6402721 : if ((before >= 0) && (after >= 0)) {
2197 330526 : ichdr.freemap[before].size += entsize;
2198 330526 : ichdr.freemap[before].size += ichdr.freemap[after].size;
2199 330526 : ichdr.freemap[after].base = 0;
2200 330526 : ichdr.freemap[after].size = 0;
2201 6072195 : } else if (before >= 0) {
2202 3771581 : ichdr.freemap[before].size += entsize;
2203 : } else {
2204 4601228 : ichdr.freemap[after].base = be16_to_cpu(entry->nameidx);
2205 2300631 : ichdr.freemap[after].size += entsize;
2206 : }
2207 : } else {
2208 : /*
2209 : * Replace smallest region (if it is smaller than free'd entry)
2210 : */
2211 19900725 : if (ichdr.freemap[smallest].size < entsize) {
2212 32937584 : ichdr.freemap[smallest].base = be16_to_cpu(entry->nameidx);
2213 16468720 : ichdr.freemap[smallest].size = entsize;
2214 : }
2215 : }
2216 :
2217 : /*
2218 : * Did we remove the first entry?
2219 : */
2220 26303597 : if (be16_to_cpu(entry->nameidx) == ichdr.firstused)
2221 : smallest = 1;
2222 : else
2223 24589429 : smallest = 0;
2224 :
2225 : /*
2226 : * Compress the remaining entries and zero out the removed stuff.
2227 : */
2228 26303597 : memset(xfs_attr3_leaf_name(leaf, args->index), 0, entsize);
2229 26303597 : ichdr.usedbytes -= entsize;
2230 26303597 : xfs_trans_log_buf(args->trans, bp,
2231 26303597 : XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index),
2232 : entsize));
2233 :
2234 26302662 : tmp = (ichdr.count - args->index) * sizeof(xfs_attr_leaf_entry_t);
2235 52605324 : memmove(entry, entry + 1, tmp);
2236 26302662 : ichdr.count--;
2237 26302662 : xfs_trans_log_buf(args->trans, bp,
2238 26302662 : XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(xfs_attr_leaf_entry_t)));
2239 :
2240 26303713 : entry = &xfs_attr3_leaf_entryp(leaf)[ichdr.count];
2241 26303713 : 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 26303713 : if (smallest) {
2250 1714304 : tmp = args->geo->blksize;
2251 1714304 : entry = xfs_attr3_leaf_entryp(leaf);
2252 22181427 : for (i = ichdr.count - 1; i >= 0; entry++, i--) {
2253 20467124 : ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused);
2254 20467124 : ASSERT(be16_to_cpu(entry->nameidx) < args->geo->blksize);
2255 :
2256 20467123 : if (be16_to_cpu(entry->nameidx) < tmp)
2257 : tmp = be16_to_cpu(entry->nameidx);
2258 : }
2259 1714303 : ichdr.firstused = tmp;
2260 1714303 : ASSERT(ichdr.firstused != 0);
2261 : } else {
2262 24589409 : ichdr.holes = 1; /* mark as needing compaction */
2263 : }
2264 26303712 : xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr);
2265 26303063 : xfs_trans_log_buf(args->trans, bp,
2266 26303063 : 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 26301975 : tmp = ichdr.usedbytes + xfs_attr3_leaf_hdr_size(leaf) +
2274 26301975 : ichdr.count * sizeof(xfs_attr_leaf_entry_t);
2275 :
2276 26301975 : 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 399 : 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 399 : struct xfs_attr_leafblock *drop_leaf = drop_blk->bp->b_addr;
2289 399 : struct xfs_attr_leafblock *save_leaf = save_blk->bp->b_addr;
2290 399 : struct xfs_attr3_icleaf_hdr drophdr;
2291 399 : struct xfs_attr3_icleaf_hdr savehdr;
2292 399 : struct xfs_attr_leaf_entry *entry;
2293 :
2294 399 : trace_xfs_attr_leaf_unbalance(state->args);
2295 :
2296 399 : xfs_attr3_leaf_hdr_from_disk(state->args->geo, &drophdr, drop_leaf);
2297 399 : xfs_attr3_leaf_hdr_from_disk(state->args->geo, &savehdr, save_leaf);
2298 399 : entry = xfs_attr3_leaf_entryp(drop_leaf);
2299 :
2300 : /*
2301 : * Save last hashval from dying block for later Btree fixup.
2302 : */
2303 399 : 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 399 : 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 1 : if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
2316 : drop_blk->bp, &drophdr)) {
2317 1 : 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 398 : struct xfs_attr_leafblock *tmp_leaf;
2333 398 : struct xfs_attr3_icleaf_hdr tmphdr;
2334 :
2335 398 : 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 1194 : memcpy(tmp_leaf, save_leaf, xfs_attr3_leaf_hdr_size(save_leaf));
2343 :
2344 398 : memset(&tmphdr, 0, sizeof(tmphdr));
2345 398 : tmphdr.magic = savehdr.magic;
2346 398 : tmphdr.forw = savehdr.forw;
2347 398 : tmphdr.back = savehdr.back;
2348 398 : tmphdr.firstused = state->args->geo->blksize;
2349 :
2350 : /* write the header to the temp buffer to initialise it */
2351 398 : xfs_attr3_leaf_hdr_to_disk(state->args->geo, tmp_leaf, &tmphdr);
2352 :
2353 398 : if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
2354 : drop_blk->bp, &drophdr)) {
2355 34 : xfs_attr3_leaf_moveents(state->args,
2356 : drop_leaf, &drophdr, 0,
2357 : tmp_leaf, &tmphdr, 0,
2358 34 : drophdr.count);
2359 34 : xfs_attr3_leaf_moveents(state->args,
2360 : save_leaf, &savehdr, 0,
2361 34 : tmp_leaf, &tmphdr, tmphdr.count,
2362 34 : savehdr.count);
2363 : } else {
2364 364 : xfs_attr3_leaf_moveents(state->args,
2365 : save_leaf, &savehdr, 0,
2366 : tmp_leaf, &tmphdr, 0,
2367 364 : savehdr.count);
2368 364 : xfs_attr3_leaf_moveents(state->args,
2369 : drop_leaf, &drophdr, 0,
2370 364 : tmp_leaf, &tmphdr, tmphdr.count,
2371 364 : drophdr.count);
2372 : }
2373 796 : memcpy(save_leaf, tmp_leaf, state->args->geo->blksize);
2374 398 : savehdr = tmphdr; /* struct copy */
2375 398 : kmem_free(tmp_leaf);
2376 : }
2377 :
2378 399 : xfs_attr3_leaf_hdr_to_disk(state->args->geo, save_leaf, &savehdr);
2379 399 : xfs_trans_log_buf(state->args->trans, save_blk->bp, 0,
2380 399 : state->args->geo->blksize - 1);
2381 :
2382 : /*
2383 : * Copy out last hashval in each block for B-tree code.
2384 : */
2385 399 : entry = xfs_attr3_leaf_entryp(save_leaf);
2386 399 : save_blk->hashval = be32_to_cpu(entry[savehdr.count - 1].hashval);
2387 399 : }
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 451784044 : xfs_attr3_leaf_lookup_int(
2408 : struct xfs_buf *bp,
2409 : struct xfs_da_args *args)
2410 : {
2411 451784044 : struct xfs_attr_leafblock *leaf;
2412 451784044 : struct xfs_attr3_icleaf_hdr ichdr;
2413 451784044 : struct xfs_attr_leaf_entry *entry;
2414 451784044 : struct xfs_attr_leaf_entry *entries;
2415 451784044 : struct xfs_attr_leaf_name_local *name_loc;
2416 451784044 : struct xfs_attr_leaf_name_remote *name_rmt;
2417 451784044 : xfs_dahash_t hashval;
2418 451784044 : int probe;
2419 451784044 : int span;
2420 :
2421 451784044 : trace_xfs_attr_leaf_lookup(args);
2422 :
2423 451812004 : leaf = bp->b_addr;
2424 451812004 : xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
2425 451820734 : entries = xfs_attr3_leaf_entryp(leaf);
2426 451820734 : 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 451820734 : hashval = args->hashval;
2435 451820734 : probe = span = ichdr.count / 2;
2436 605367108 : for (entry = &entries[probe]; span > 4; entry = &entries[probe]) {
2437 426236856 : span /= 2;
2438 852473712 : if (be32_to_cpu(entry->hashval) < hashval)
2439 97778872 : probe += span;
2440 328457984 : else if (be32_to_cpu(entry->hashval) > hashval)
2441 55767502 : probe -= span;
2442 : else
2443 : break;
2444 : }
2445 451820734 : if (!(probe >= 0 && (!ichdr.count || probe < ichdr.count))) {
2446 0 : xfs_buf_mark_corrupt(bp);
2447 0 : return -EFSCORRUPTED;
2448 : }
2449 452840328 : 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 5394115207 : while (probe > 0 && be32_to_cpu(entry->hashval) >= hashval) {
2459 2405959724 : entry--;
2460 2405959724 : probe--;
2461 : }
2462 1505113059 : while (probe < ichdr.count &&
2463 722722592 : be32_to_cpu(entry->hashval) < hashval) {
2464 330569733 : entry++;
2465 330569733 : probe++;
2466 : }
2467 843964217 : if (probe == ichdr.count || be32_to_cpu(entry->hashval) != hashval) {
2468 91576319 : args->index = probe;
2469 91576319 : return -ENOATTR;
2470 : }
2471 :
2472 : /*
2473 : * Duplicate keys may be present, so search all of them for a match.
2474 : */
2475 9545939651 : for (; probe < ichdr.count && (be32_to_cpu(entry->hashval) == hashval);
2476 4563689719 : entry++, probe++) {
2477 : /*
2478 : * GROT: Add code to remove incomplete entries.
2479 : */
2480 4622005517 : if (entry->flags & XFS_ATTR_LOCAL) {
2481 4622005218 : name_loc = xfs_attr3_leaf_name_local(leaf, probe);
2482 4622006484 : if (!xfs_attr_match(args, name_loc->namelen,
2483 4622005218 : name_loc->nameval, entry->flags))
2484 4563689717 : continue;
2485 58316767 : args->index = probe;
2486 58316767 : return -EEXIST;
2487 : } else {
2488 299 : name_rmt = xfs_attr3_leaf_name_remote(leaf, probe);
2489 299 : if (!xfs_attr_match(args, name_rmt->namelen,
2490 299 : name_rmt->name, entry->flags))
2491 2 : continue;
2492 297 : args->index = probe;
2493 297 : args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen);
2494 297 : args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
2495 594 : args->rmtblkcnt = xfs_attr3_rmt_blocks(
2496 297 : args->dp->i_mount,
2497 : args->rmtvaluelen);
2498 297 : return -EEXIST;
2499 : }
2500 : }
2501 301928617 : args->index = probe;
2502 301928617 : 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 5090361 : xfs_attr3_leaf_getvalue(
2515 : struct xfs_buf *bp,
2516 : struct xfs_da_args *args)
2517 : {
2518 5090361 : struct xfs_attr_leafblock *leaf;
2519 5090361 : struct xfs_attr3_icleaf_hdr ichdr;
2520 5090361 : struct xfs_attr_leaf_entry *entry;
2521 5090361 : struct xfs_attr_leaf_name_local *name_loc;
2522 5090361 : struct xfs_attr_leaf_name_remote *name_rmt;
2523 :
2524 5090361 : leaf = bp->b_addr;
2525 5090361 : xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
2526 5090403 : ASSERT(ichdr.count < args->geo->blksize / 8);
2527 5090403 : ASSERT(args->index < ichdr.count);
2528 :
2529 5090403 : entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
2530 5090403 : if (entry->flags & XFS_ATTR_LOCAL) {
2531 5090154 : name_loc = xfs_attr3_leaf_name_local(leaf, args->index);
2532 5090154 : ASSERT(name_loc->namelen == args->namelen);
2533 10180308 : ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0);
2534 5090154 : return xfs_attr_copy_value(args,
2535 5090154 : &name_loc->nameval[args->namelen],
2536 5090154 : be16_to_cpu(name_loc->valuelen));
2537 : }
2538 :
2539 249 : name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
2540 249 : ASSERT(name_rmt->namelen == args->namelen);
2541 498 : ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0);
2542 249 : args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen);
2543 249 : args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
2544 249 : args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount,
2545 : args->rmtvaluelen);
2546 249 : 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 211447 : 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 211447 : struct xfs_attr_leaf_entry *entry_s;
2570 211447 : struct xfs_attr_leaf_entry *entry_d;
2571 211447 : int desti;
2572 211447 : int tmp;
2573 211447 : int i;
2574 :
2575 : /*
2576 : * Check for nothing to do.
2577 : */
2578 211447 : if (count == 0)
2579 : return;
2580 :
2581 : /*
2582 : * Set up environment.
2583 : */
2584 211447 : ASSERT(ichdr_s->magic == XFS_ATTR_LEAF_MAGIC ||
2585 : ichdr_s->magic == XFS_ATTR3_LEAF_MAGIC);
2586 211447 : ASSERT(ichdr_s->magic == ichdr_d->magic);
2587 211447 : ASSERT(ichdr_s->count > 0 && ichdr_s->count < args->geo->blksize / 8);
2588 422894 : ASSERT(ichdr_s->firstused >= (ichdr_s->count * sizeof(*entry_s))
2589 : + xfs_attr3_leaf_hdr_size(leaf_s));
2590 211447 : ASSERT(ichdr_d->count < args->geo->blksize / 8);
2591 422894 : ASSERT(ichdr_d->firstused >= (ichdr_d->count * sizeof(*entry_d))
2592 : + xfs_attr3_leaf_hdr_size(leaf_d));
2593 :
2594 211447 : ASSERT(start_s < ichdr_s->count);
2595 211447 : ASSERT(start_d <= ichdr_d->count);
2596 211447 : ASSERT(count <= ichdr_s->count);
2597 :
2598 :
2599 : /*
2600 : * Move the entries in the destination leaf up to make a hole?
2601 : */
2602 211447 : if (start_d < ichdr_d->count) {
2603 1 : tmp = ichdr_d->count - start_d;
2604 1 : tmp *= sizeof(xfs_attr_leaf_entry_t);
2605 1 : entry_s = &xfs_attr3_leaf_entryp(leaf_d)[start_d];
2606 1 : entry_d = &xfs_attr3_leaf_entryp(leaf_d)[start_d + count];
2607 2 : 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 211447 : entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
2615 211447 : entry_d = &xfs_attr3_leaf_entryp(leaf_d)[start_d];
2616 211447 : desti = start_d;
2617 9501098 : for (i = 0; i < count; entry_s++, entry_d++, desti++, i++) {
2618 9289651 : ASSERT(be16_to_cpu(entry_s->nameidx) >= ichdr_s->firstused);
2619 9289651 : 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 9289651 : ichdr_d->firstused -= tmp;
2637 : /* both on-disk, don't endian flip twice */
2638 9289651 : entry_d->hashval = entry_s->hashval;
2639 9289651 : entry_d->nameidx = cpu_to_be16(ichdr_d->firstused);
2640 9289651 : entry_d->flags = entry_s->flags;
2641 9289651 : ASSERT(be16_to_cpu(entry_d->nameidx) + tmp
2642 : <= args->geo->blksize);
2643 9289651 : memmove(xfs_attr3_leaf_name(leaf_d, desti),
2644 : xfs_attr3_leaf_name(leaf_s, start_s + i), tmp);
2645 9289651 : ASSERT(be16_to_cpu(entry_s->nameidx) + tmp
2646 : <= args->geo->blksize);
2647 9289651 : memset(xfs_attr3_leaf_name(leaf_s, start_s + i), 0, tmp);
2648 9289651 : ichdr_s->usedbytes -= tmp;
2649 9289651 : ichdr_d->usedbytes += tmp;
2650 9289651 : ichdr_s->count -= 1;
2651 9289651 : ichdr_d->count += 1;
2652 9289651 : tmp = ichdr_d->count * sizeof(xfs_attr_leaf_entry_t)
2653 9289651 : + xfs_attr3_leaf_hdr_size(leaf_d);
2654 9289651 : 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 211447 : if (start_s == ichdr_s->count) {
2664 211447 : tmp = count * sizeof(xfs_attr_leaf_entry_t);
2665 211447 : entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
2666 211447 : ASSERT(((char *)entry_s + tmp) <=
2667 : ((char *)leaf_s + args->geo->blksize));
2668 422894 : 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 211447 : ichdr_d->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_d);
2690 211447 : ichdr_d->freemap[0].base += ichdr_d->count * sizeof(xfs_attr_leaf_entry_t);
2691 211447 : ichdr_d->freemap[0].size = ichdr_d->firstused - ichdr_d->freemap[0].base;
2692 211447 : ichdr_d->freemap[1].base = 0;
2693 211447 : ichdr_d->freemap[2].base = 0;
2694 211447 : ichdr_d->freemap[1].size = 0;
2695 211447 : ichdr_d->freemap[2].size = 0;
2696 211447 : 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 307972944 : xfs_attr_leaf_lasthash(
2704 : struct xfs_buf *bp,
2705 : int *count)
2706 : {
2707 307972944 : struct xfs_attr3_icleaf_hdr ichdr;
2708 307972944 : struct xfs_attr_leaf_entry *entries;
2709 307972944 : struct xfs_mount *mp = bp->b_mount;
2710 :
2711 307972944 : xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, bp->b_addr);
2712 307972984 : entries = xfs_attr3_leaf_entryp(bp->b_addr);
2713 307972984 : if (count)
2714 2568525 : *count = ichdr.count;
2715 307972984 : if (!ichdr.count)
2716 : return 0;
2717 307972978 : 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 145000491 : xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
2726 : {
2727 145000491 : struct xfs_attr_leaf_entry *entries;
2728 145000491 : xfs_attr_leaf_name_local_t *name_loc;
2729 145000491 : xfs_attr_leaf_name_remote_t *name_rmt;
2730 145000491 : int size;
2731 :
2732 145000491 : entries = xfs_attr3_leaf_entryp(leaf);
2733 145000491 : if (entries[index].flags & XFS_ATTR_LOCAL) {
2734 144999571 : name_loc = xfs_attr3_leaf_name_local(leaf, index);
2735 144999571 : size = xfs_attr_leaf_entsize_local(name_loc->namelen,
2736 144999571 : be16_to_cpu(name_loc->valuelen));
2737 : } else {
2738 920 : name_rmt = xfs_attr3_leaf_name_remote(leaf, index);
2739 920 : size = xfs_attr_leaf_entsize_remote(name_rmt->namelen);
2740 : }
2741 145000491 : 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 232290922 : xfs_attr_leaf_newentsize(
2752 : struct xfs_da_args *args,
2753 : int *local)
2754 : {
2755 232290922 : int size;
2756 :
2757 232290922 : size = xfs_attr_leaf_entsize_local(args->namelen, args->valuelen);
2758 232290922 : if (size < xfs_attr_leaf_entsize_local_max(args->geo->blksize)) {
2759 232288984 : if (local)
2760 123690655 : *local = 1;
2761 232288984 : return size;
2762 : }
2763 1938 : if (local)
2764 1034 : *local = 0;
2765 1938 : 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 450 : xfs_attr3_leaf_clearflag(
2778 : struct xfs_da_args *args)
2779 : {
2780 450 : struct xfs_attr_leafblock *leaf;
2781 450 : struct xfs_attr_leaf_entry *entry;
2782 450 : struct xfs_attr_leaf_name_remote *name_rmt;
2783 450 : struct xfs_buf *bp;
2784 450 : int error;
2785 : #ifdef DEBUG
2786 450 : struct xfs_attr3_icleaf_hdr ichdr;
2787 450 : xfs_attr_leaf_name_local_t *name_loc;
2788 450 : int namelen;
2789 450 : char *name;
2790 : #endif /* DEBUG */
2791 :
2792 450 : trace_xfs_attr_leaf_clearflag(args);
2793 : /*
2794 : * Set up the operation.
2795 : */
2796 450 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, &bp);
2797 450 : if (error)
2798 : return error;
2799 :
2800 450 : leaf = bp->b_addr;
2801 450 : entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
2802 450 : ASSERT(entry->flags & XFS_ATTR_INCOMPLETE);
2803 :
2804 : #ifdef DEBUG
2805 450 : xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
2806 450 : ASSERT(args->index < ichdr.count);
2807 450 : ASSERT(args->index >= 0);
2808 :
2809 450 : 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 450 : name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
2815 450 : namelen = name_rmt->namelen;
2816 450 : name = (char *)name_rmt->name;
2817 : }
2818 900 : ASSERT(be32_to_cpu(entry->hashval) == args->hashval);
2819 450 : ASSERT(namelen == args->namelen);
2820 900 : ASSERT(memcmp(name, args->name, namelen) == 0);
2821 : #endif /* DEBUG */
2822 :
2823 450 : entry->flags &= ~XFS_ATTR_INCOMPLETE;
2824 450 : xfs_trans_log_buf(args->trans, bp,
2825 450 : XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
2826 :
2827 450 : if (args->rmtblkno) {
2828 450 : ASSERT((entry->flags & XFS_ATTR_LOCAL) == 0);
2829 450 : name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
2830 450 : name_rmt->valueblk = cpu_to_be32(args->rmtblkno);
2831 450 : name_rmt->valuelen = cpu_to_be32(args->rmtvaluelen);
2832 450 : xfs_trans_log_buf(args->trans, bp,
2833 450 : 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 331873 : xfs_attr3_leaf_setflag(
2844 : struct xfs_da_args *args)
2845 : {
2846 331873 : struct xfs_attr_leafblock *leaf;
2847 331873 : struct xfs_attr_leaf_entry *entry;
2848 331873 : struct xfs_attr_leaf_name_remote *name_rmt;
2849 331873 : struct xfs_buf *bp;
2850 331873 : int error;
2851 : #ifdef DEBUG
2852 331873 : struct xfs_attr3_icleaf_hdr ichdr;
2853 : #endif
2854 :
2855 331873 : trace_xfs_attr_leaf_setflag(args);
2856 :
2857 : /*
2858 : * Set up the operation.
2859 : */
2860 331873 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, &bp);
2861 331873 : if (error)
2862 : return error;
2863 :
2864 331872 : leaf = bp->b_addr;
2865 : #ifdef DEBUG
2866 331872 : xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
2867 331871 : ASSERT(args->index < ichdr.count);
2868 331871 : ASSERT(args->index >= 0);
2869 : #endif
2870 331871 : entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
2871 :
2872 331871 : ASSERT((entry->flags & XFS_ATTR_INCOMPLETE) == 0);
2873 331871 : entry->flags |= XFS_ATTR_INCOMPLETE;
2874 331871 : xfs_trans_log_buf(args->trans, bp,
2875 331871 : XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
2876 331873 : if ((entry->flags & XFS_ATTR_LOCAL) == 0) {
2877 12 : name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
2878 12 : name_rmt->valueblk = 0;
2879 12 : name_rmt->valuelen = 0;
2880 12 : xfs_trans_log_buf(args->trans, bp,
2881 12 : 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 10270572 : xfs_attr3_leaf_flipflags(
2896 : struct xfs_da_args *args)
2897 : {
2898 10270572 : struct xfs_attr_leafblock *leaf1;
2899 10270572 : struct xfs_attr_leafblock *leaf2;
2900 10270572 : struct xfs_attr_leaf_entry *entry1;
2901 10270572 : struct xfs_attr_leaf_entry *entry2;
2902 10270572 : struct xfs_attr_leaf_name_remote *name_rmt;
2903 10270572 : struct xfs_buf *bp1;
2904 10270572 : struct xfs_buf *bp2;
2905 10270572 : int error;
2906 : #ifdef DEBUG
2907 10270572 : struct xfs_attr3_icleaf_hdr ichdr1;
2908 10270572 : struct xfs_attr3_icleaf_hdr ichdr2;
2909 10270572 : xfs_attr_leaf_name_local_t *name_loc;
2910 10270572 : int namelen1, namelen2;
2911 10270572 : char *name1, *name2;
2912 : #endif /* DEBUG */
2913 :
2914 10270572 : trace_xfs_attr_leaf_flipflags(args);
2915 :
2916 : /*
2917 : * Read the block containing the "old" attr
2918 : */
2919 10271322 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, &bp1);
2920 10270865 : if (error)
2921 : return error;
2922 :
2923 : /*
2924 : * Read the block containing the "new" attr, if it is different
2925 : */
2926 10270865 : if (args->blkno2 != args->blkno) {
2927 127 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno2,
2928 : &bp2);
2929 127 : if (error)
2930 : return error;
2931 : } else {
2932 10270738 : bp2 = bp1;
2933 : }
2934 :
2935 10270865 : leaf1 = bp1->b_addr;
2936 10270865 : entry1 = &xfs_attr3_leaf_entryp(leaf1)[args->index];
2937 :
2938 10270865 : leaf2 = bp2->b_addr;
2939 10270865 : entry2 = &xfs_attr3_leaf_entryp(leaf2)[args->index2];
2940 :
2941 : #ifdef DEBUG
2942 10270865 : xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr1, leaf1);
2943 10271150 : ASSERT(args->index < ichdr1.count);
2944 10271150 : ASSERT(args->index >= 0);
2945 :
2946 10271150 : xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr2, leaf2);
2947 10270558 : ASSERT(args->index2 < ichdr2.count);
2948 10270558 : ASSERT(args->index2 >= 0);
2949 :
2950 10270558 : if (entry1->flags & XFS_ATTR_LOCAL) {
2951 10270556 : name_loc = xfs_attr3_leaf_name_local(leaf1, args->index);
2952 10270556 : namelen1 = name_loc->namelen;
2953 10270556 : name1 = (char *)name_loc->nameval;
2954 : } else {
2955 2 : name_rmt = xfs_attr3_leaf_name_remote(leaf1, args->index);
2956 2 : namelen1 = name_rmt->namelen;
2957 2 : name1 = (char *)name_rmt->name;
2958 : }
2959 10270558 : if (entry2->flags & XFS_ATTR_LOCAL) {
2960 10271355 : name_loc = xfs_attr3_leaf_name_local(leaf2, args->index2);
2961 10271355 : namelen2 = name_loc->namelen;
2962 10271355 : name2 = (char *)name_loc->nameval;
2963 : } else {
2964 1 : name_rmt = xfs_attr3_leaf_name_remote(leaf2, args->index2);
2965 1 : namelen2 = name_rmt->namelen;
2966 1 : name2 = (char *)name_rmt->name;
2967 : }
2968 30811674 : ASSERT(be32_to_cpu(entry1->hashval) == be32_to_cpu(entry2->hashval));
2969 10270558 : ASSERT(namelen1 == namelen2);
2970 20541116 : ASSERT(memcmp(name1, name2, namelen1) == 0);
2971 : #endif /* DEBUG */
2972 :
2973 10270558 : ASSERT(entry1->flags & XFS_ATTR_INCOMPLETE);
2974 10270558 : ASSERT((entry2->flags & XFS_ATTR_INCOMPLETE) == 0);
2975 :
2976 10270558 : entry1->flags &= ~XFS_ATTR_INCOMPLETE;
2977 10270558 : xfs_trans_log_buf(args->trans, bp1,
2978 10270558 : XFS_DA_LOGRANGE(leaf1, entry1, sizeof(*entry1)));
2979 10270852 : if (args->rmtblkno) {
2980 2 : ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0);
2981 2 : name_rmt = xfs_attr3_leaf_name_remote(leaf1, args->index);
2982 2 : name_rmt->valueblk = cpu_to_be32(args->rmtblkno);
2983 2 : name_rmt->valuelen = cpu_to_be32(args->rmtvaluelen);
2984 2 : xfs_trans_log_buf(args->trans, bp1,
2985 2 : XFS_DA_LOGRANGE(leaf1, name_rmt, sizeof(*name_rmt)));
2986 : }
2987 :
2988 10270852 : entry2->flags |= XFS_ATTR_INCOMPLETE;
2989 10270852 : xfs_trans_log_buf(args->trans, bp2,
2990 10270852 : XFS_DA_LOGRANGE(leaf2, entry2, sizeof(*entry2)));
2991 10271033 : if ((entry2->flags & XFS_ATTR_LOCAL) == 0) {
2992 4 : name_rmt = xfs_attr3_leaf_name_remote(leaf2, args->index2);
2993 4 : name_rmt->valueblk = 0;
2994 4 : name_rmt->valuelen = 0;
2995 4 : xfs_trans_log_buf(args->trans, bp2,
2996 4 : XFS_DA_LOGRANGE(leaf2, name_rmt, sizeof(*name_rmt)));
2997 : }
2998 :
2999 : return 0;
3000 : }
|