2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include "xfs_types.h"
23 #include "xfs_trans.h"
26 #include "xfs_mount.h"
27 #include "xfs_da_btree.h"
28 #include "xfs_bmap_btree.h"
29 #include "xfs_alloc_btree.h"
30 #include "xfs_ialloc_btree.h"
31 #include "xfs_alloc.h"
32 #include "xfs_btree.h"
33 #include "xfs_attr_sf.h"
34 #include "xfs_dinode.h"
35 #include "xfs_inode.h"
36 #include "xfs_inode_item.h"
39 #include "xfs_attr_leaf.h"
40 #include "xfs_error.h"
41 #include "xfs_trace.h"
46 * Routines to implement leaf blocks of attributes as Btrees of hashed names.
49 /*========================================================================
50 * Function prototypes for the kernel.
51 *========================================================================*/
54 * Routines used for growing the Btree.
56 STATIC
int xfs_attr_leaf_create(xfs_da_args_t
*args
, xfs_dablk_t which_block
,
57 struct xfs_buf
**bpp
);
58 STATIC
int xfs_attr_leaf_add_work(struct xfs_buf
*leaf_buffer
,
59 xfs_da_args_t
*args
, int freemap_index
);
60 STATIC
void xfs_attr_leaf_compact(struct xfs_da_args
*args
,
61 struct xfs_buf
*leaf_buffer
);
62 STATIC
void xfs_attr_leaf_rebalance(xfs_da_state_t
*state
,
63 xfs_da_state_blk_t
*blk1
,
64 xfs_da_state_blk_t
*blk2
);
65 STATIC
int xfs_attr_leaf_figure_balance(xfs_da_state_t
*state
,
66 xfs_da_state_blk_t
*leaf_blk_1
,
67 xfs_da_state_blk_t
*leaf_blk_2
,
68 int *number_entries_in_blk1
,
69 int *number_usedbytes_in_blk1
);
72 * Routines used for shrinking the Btree.
74 STATIC
int xfs_attr_node_inactive(xfs_trans_t
**trans
, xfs_inode_t
*dp
,
75 struct xfs_buf
*bp
, int level
);
76 STATIC
int xfs_attr_leaf_inactive(xfs_trans_t
**trans
, xfs_inode_t
*dp
,
78 STATIC
int xfs_attr_leaf_freextent(xfs_trans_t
**trans
, xfs_inode_t
*dp
,
79 xfs_dablk_t blkno
, int blkcnt
);
84 STATIC
void xfs_attr_leaf_moveents(xfs_attr_leafblock_t
*src_leaf
,
86 xfs_attr_leafblock_t
*dst_leaf
,
87 int dst_start
, int move_count
,
89 STATIC
int xfs_attr_leaf_entsize(xfs_attr_leafblock_t
*leaf
, int index
);
95 struct xfs_mount
*mp
= bp
->b_target
->bt_mount
;
96 struct xfs_attr_leaf_hdr
*hdr
= bp
->b_addr
;
99 block_ok
= hdr
->info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
);
101 XFS_CORRUPTION_ERROR(__func__
, XFS_ERRLEVEL_LOW
, mp
, hdr
);
102 xfs_buf_ioerror(bp
, EFSCORRUPTED
);
107 xfs_attr_leaf_read_verify(
110 xfs_attr_leaf_verify(bp
);
114 xfs_attr_leaf_write_verify(
117 xfs_attr_leaf_verify(bp
);
120 const struct xfs_buf_ops xfs_attr_leaf_buf_ops
= {
121 .verify_read
= xfs_attr_leaf_read_verify
,
122 .verify_write
= xfs_attr_leaf_write_verify
,
127 struct xfs_trans
*tp
,
128 struct xfs_inode
*dp
,
130 xfs_daddr_t mappedbno
,
131 struct xfs_buf
**bpp
)
133 return xfs_da_read_buf(tp
, dp
, bno
, mappedbno
, bpp
,
134 XFS_ATTR_FORK
, &xfs_attr_leaf_buf_ops
);
137 /*========================================================================
138 * Namespace helper routines
139 *========================================================================*/
142 * If namespace bits don't match return 0.
143 * If all match then return 1.
146 xfs_attr_namesp_match(int arg_flags
, int ondisk_flags
)
148 return XFS_ATTR_NSP_ONDISK(ondisk_flags
) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags
);
152 /*========================================================================
153 * External routines when attribute fork size < XFS_LITINO(mp).
154 *========================================================================*/
157 * Query whether the requested number of additional bytes of extended
158 * attribute space will be able to fit inline.
160 * Returns zero if not, else the di_forkoff fork offset to be used in the
161 * literal area for attribute data once the new bytes have been added.
163 * di_forkoff must be 8 byte aligned, hence is stored as a >>3 value;
164 * special case for dev/uuid inodes, they have fixed size data forks.
167 xfs_attr_shortform_bytesfit(xfs_inode_t
*dp
, int bytes
)
170 int minforkoff
; /* lower limit on valid forkoff locations */
171 int maxforkoff
; /* upper limit on valid forkoff locations */
173 xfs_mount_t
*mp
= dp
->i_mount
;
175 offset
= (XFS_LITINO(mp
) - bytes
) >> 3; /* rounded down */
177 switch (dp
->i_d
.di_format
) {
178 case XFS_DINODE_FMT_DEV
:
179 minforkoff
= roundup(sizeof(xfs_dev_t
), 8) >> 3;
180 return (offset
>= minforkoff
) ? minforkoff
: 0;
181 case XFS_DINODE_FMT_UUID
:
182 minforkoff
= roundup(sizeof(uuid_t
), 8) >> 3;
183 return (offset
>= minforkoff
) ? minforkoff
: 0;
187 * If the requested numbers of bytes is smaller or equal to the
188 * current attribute fork size we can always proceed.
190 * Note that if_bytes in the data fork might actually be larger than
191 * the current data fork size is due to delalloc extents. In that
192 * case either the extent count will go down when they are converted
193 * to real extents, or the delalloc conversion will take care of the
194 * literal area rebalancing.
196 if (bytes
<= XFS_IFORK_ASIZE(dp
))
197 return dp
->i_d
.di_forkoff
;
200 * For attr2 we can try to move the forkoff if there is space in the
201 * literal area, but for the old format we are done if there is no
202 * space in the fixed attribute fork.
204 if (!(mp
->m_flags
& XFS_MOUNT_ATTR2
))
207 dsize
= dp
->i_df
.if_bytes
;
209 switch (dp
->i_d
.di_format
) {
210 case XFS_DINODE_FMT_EXTENTS
:
212 * If there is no attr fork and the data fork is extents,
213 * determine if creating the default attr fork will result
214 * in the extents form migrating to btree. If so, the
215 * minimum offset only needs to be the space required for
218 if (!dp
->i_d
.di_forkoff
&& dp
->i_df
.if_bytes
>
219 xfs_default_attroffset(dp
))
220 dsize
= XFS_BMDR_SPACE_CALC(MINDBTPTRS
);
222 case XFS_DINODE_FMT_BTREE
:
224 * If we have a data btree then keep forkoff if we have one,
225 * otherwise we are adding a new attr, so then we set
226 * minforkoff to where the btree root can finish so we have
227 * plenty of room for attrs
229 if (dp
->i_d
.di_forkoff
) {
230 if (offset
< dp
->i_d
.di_forkoff
)
232 return dp
->i_d
.di_forkoff
;
234 dsize
= XFS_BMAP_BROOT_SPACE(dp
->i_df
.if_broot
);
239 * A data fork btree root must have space for at least
240 * MINDBTPTRS key/ptr pairs if the data fork is small or empty.
242 minforkoff
= MAX(dsize
, XFS_BMDR_SPACE_CALC(MINDBTPTRS
));
243 minforkoff
= roundup(minforkoff
, 8) >> 3;
245 /* attr fork btree root can have at least this many key/ptr pairs */
246 maxforkoff
= XFS_LITINO(mp
) - XFS_BMDR_SPACE_CALC(MINABTPTRS
);
247 maxforkoff
= maxforkoff
>> 3; /* rounded down */
249 if (offset
>= maxforkoff
)
251 if (offset
>= minforkoff
)
257 * Switch on the ATTR2 superblock bit (implies also FEATURES2)
260 xfs_sbversion_add_attr2(xfs_mount_t
*mp
, xfs_trans_t
*tp
)
262 if ((mp
->m_flags
& XFS_MOUNT_ATTR2
) &&
263 !(xfs_sb_version_hasattr2(&mp
->m_sb
))) {
264 spin_lock(&mp
->m_sb_lock
);
265 if (!xfs_sb_version_hasattr2(&mp
->m_sb
)) {
266 xfs_sb_version_addattr2(&mp
->m_sb
);
267 spin_unlock(&mp
->m_sb_lock
);
268 xfs_mod_sb(tp
, XFS_SB_VERSIONNUM
| XFS_SB_FEATURES2
);
270 spin_unlock(&mp
->m_sb_lock
);
275 * Create the initial contents of a shortform attribute list.
278 xfs_attr_shortform_create(xfs_da_args_t
*args
)
280 xfs_attr_sf_hdr_t
*hdr
;
284 trace_xfs_attr_sf_create(args
);
290 ASSERT(ifp
->if_bytes
== 0);
291 if (dp
->i_d
.di_aformat
== XFS_DINODE_FMT_EXTENTS
) {
292 ifp
->if_flags
&= ~XFS_IFEXTENTS
; /* just in case */
293 dp
->i_d
.di_aformat
= XFS_DINODE_FMT_LOCAL
;
294 ifp
->if_flags
|= XFS_IFINLINE
;
296 ASSERT(ifp
->if_flags
& XFS_IFINLINE
);
298 xfs_idata_realloc(dp
, sizeof(*hdr
), XFS_ATTR_FORK
);
299 hdr
= (xfs_attr_sf_hdr_t
*)ifp
->if_u1
.if_data
;
301 hdr
->totsize
= cpu_to_be16(sizeof(*hdr
));
302 xfs_trans_log_inode(args
->trans
, dp
, XFS_ILOG_CORE
| XFS_ILOG_ADATA
);
306 * Add a name/value pair to the shortform attribute list.
307 * Overflow from the inode has already been checked for.
310 xfs_attr_shortform_add(xfs_da_args_t
*args
, int forkoff
)
312 xfs_attr_shortform_t
*sf
;
313 xfs_attr_sf_entry_t
*sfe
;
319 trace_xfs_attr_sf_add(args
);
323 dp
->i_d
.di_forkoff
= forkoff
;
326 ASSERT(ifp
->if_flags
& XFS_IFINLINE
);
327 sf
= (xfs_attr_shortform_t
*)ifp
->if_u1
.if_data
;
329 for (i
= 0; i
< sf
->hdr
.count
; sfe
= XFS_ATTR_SF_NEXTENTRY(sfe
), i
++) {
331 if (sfe
->namelen
!= args
->namelen
)
333 if (memcmp(args
->name
, sfe
->nameval
, args
->namelen
) != 0)
335 if (!xfs_attr_namesp_match(args
->flags
, sfe
->flags
))
341 offset
= (char *)sfe
- (char *)sf
;
342 size
= XFS_ATTR_SF_ENTSIZE_BYNAME(args
->namelen
, args
->valuelen
);
343 xfs_idata_realloc(dp
, size
, XFS_ATTR_FORK
);
344 sf
= (xfs_attr_shortform_t
*)ifp
->if_u1
.if_data
;
345 sfe
= (xfs_attr_sf_entry_t
*)((char *)sf
+ offset
);
347 sfe
->namelen
= args
->namelen
;
348 sfe
->valuelen
= args
->valuelen
;
349 sfe
->flags
= XFS_ATTR_NSP_ARGS_TO_ONDISK(args
->flags
);
350 memcpy(sfe
->nameval
, args
->name
, args
->namelen
);
351 memcpy(&sfe
->nameval
[args
->namelen
], args
->value
, args
->valuelen
);
353 be16_add_cpu(&sf
->hdr
.totsize
, size
);
354 xfs_trans_log_inode(args
->trans
, dp
, XFS_ILOG_CORE
| XFS_ILOG_ADATA
);
356 xfs_sbversion_add_attr2(mp
, args
->trans
);
360 * After the last attribute is removed revert to original inode format,
361 * making all literal area available to the data fork once more.
365 struct xfs_inode
*ip
,
366 struct xfs_trans
*tp
)
368 xfs_idestroy_fork(ip
, XFS_ATTR_FORK
);
369 ip
->i_d
.di_forkoff
= 0;
370 ip
->i_d
.di_aformat
= XFS_DINODE_FMT_EXTENTS
;
372 ASSERT(ip
->i_d
.di_anextents
== 0);
373 ASSERT(ip
->i_afp
== NULL
);
375 xfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
379 * Remove an attribute from the shortform attribute list structure.
382 xfs_attr_shortform_remove(xfs_da_args_t
*args
)
384 xfs_attr_shortform_t
*sf
;
385 xfs_attr_sf_entry_t
*sfe
;
386 int base
, size
=0, end
, totsize
, i
;
390 trace_xfs_attr_sf_remove(args
);
394 base
= sizeof(xfs_attr_sf_hdr_t
);
395 sf
= (xfs_attr_shortform_t
*)dp
->i_afp
->if_u1
.if_data
;
398 for (i
= 0; i
< end
; sfe
= XFS_ATTR_SF_NEXTENTRY(sfe
),
400 size
= XFS_ATTR_SF_ENTSIZE(sfe
);
401 if (sfe
->namelen
!= args
->namelen
)
403 if (memcmp(sfe
->nameval
, args
->name
, args
->namelen
) != 0)
405 if (!xfs_attr_namesp_match(args
->flags
, sfe
->flags
))
410 return(XFS_ERROR(ENOATTR
));
413 * Fix up the attribute fork data, covering the hole
416 totsize
= be16_to_cpu(sf
->hdr
.totsize
);
418 memmove(&((char *)sf
)[base
], &((char *)sf
)[end
], totsize
- end
);
420 be16_add_cpu(&sf
->hdr
.totsize
, -size
);
423 * Fix up the start offset of the attribute fork
426 if (totsize
== sizeof(xfs_attr_sf_hdr_t
) &&
427 (mp
->m_flags
& XFS_MOUNT_ATTR2
) &&
428 (dp
->i_d
.di_format
!= XFS_DINODE_FMT_BTREE
) &&
429 !(args
->op_flags
& XFS_DA_OP_ADDNAME
)) {
430 xfs_attr_fork_reset(dp
, args
->trans
);
432 xfs_idata_realloc(dp
, -size
, XFS_ATTR_FORK
);
433 dp
->i_d
.di_forkoff
= xfs_attr_shortform_bytesfit(dp
, totsize
);
434 ASSERT(dp
->i_d
.di_forkoff
);
435 ASSERT(totsize
> sizeof(xfs_attr_sf_hdr_t
) ||
436 (args
->op_flags
& XFS_DA_OP_ADDNAME
) ||
437 !(mp
->m_flags
& XFS_MOUNT_ATTR2
) ||
438 dp
->i_d
.di_format
== XFS_DINODE_FMT_BTREE
);
439 xfs_trans_log_inode(args
->trans
, dp
,
440 XFS_ILOG_CORE
| XFS_ILOG_ADATA
);
443 xfs_sbversion_add_attr2(mp
, args
->trans
);
449 * Look up a name in a shortform attribute list structure.
453 xfs_attr_shortform_lookup(xfs_da_args_t
*args
)
455 xfs_attr_shortform_t
*sf
;
456 xfs_attr_sf_entry_t
*sfe
;
460 trace_xfs_attr_sf_lookup(args
);
462 ifp
= args
->dp
->i_afp
;
463 ASSERT(ifp
->if_flags
& XFS_IFINLINE
);
464 sf
= (xfs_attr_shortform_t
*)ifp
->if_u1
.if_data
;
466 for (i
= 0; i
< sf
->hdr
.count
;
467 sfe
= XFS_ATTR_SF_NEXTENTRY(sfe
), i
++) {
468 if (sfe
->namelen
!= args
->namelen
)
470 if (memcmp(args
->name
, sfe
->nameval
, args
->namelen
) != 0)
472 if (!xfs_attr_namesp_match(args
->flags
, sfe
->flags
))
474 return(XFS_ERROR(EEXIST
));
476 return(XFS_ERROR(ENOATTR
));
480 * Look up a name in a shortform attribute list structure.
484 xfs_attr_shortform_getvalue(xfs_da_args_t
*args
)
486 xfs_attr_shortform_t
*sf
;
487 xfs_attr_sf_entry_t
*sfe
;
490 ASSERT(args
->dp
->i_d
.di_aformat
== XFS_IFINLINE
);
491 sf
= (xfs_attr_shortform_t
*)args
->dp
->i_afp
->if_u1
.if_data
;
493 for (i
= 0; i
< sf
->hdr
.count
;
494 sfe
= XFS_ATTR_SF_NEXTENTRY(sfe
), i
++) {
495 if (sfe
->namelen
!= args
->namelen
)
497 if (memcmp(args
->name
, sfe
->nameval
, args
->namelen
) != 0)
499 if (!xfs_attr_namesp_match(args
->flags
, sfe
->flags
))
501 if (args
->flags
& ATTR_KERNOVAL
) {
502 args
->valuelen
= sfe
->valuelen
;
503 return(XFS_ERROR(EEXIST
));
505 if (args
->valuelen
< sfe
->valuelen
) {
506 args
->valuelen
= sfe
->valuelen
;
507 return(XFS_ERROR(ERANGE
));
509 args
->valuelen
= sfe
->valuelen
;
510 memcpy(args
->value
, &sfe
->nameval
[args
->namelen
],
512 return(XFS_ERROR(EEXIST
));
514 return(XFS_ERROR(ENOATTR
));
518 * Convert from using the shortform to the leaf.
521 xfs_attr_shortform_to_leaf(xfs_da_args_t
*args
)
524 xfs_attr_shortform_t
*sf
;
525 xfs_attr_sf_entry_t
*sfe
;
533 trace_xfs_attr_sf_to_leaf(args
);
537 sf
= (xfs_attr_shortform_t
*)ifp
->if_u1
.if_data
;
538 size
= be16_to_cpu(sf
->hdr
.totsize
);
539 tmpbuffer
= kmem_alloc(size
, KM_SLEEP
);
540 ASSERT(tmpbuffer
!= NULL
);
541 memcpy(tmpbuffer
, ifp
->if_u1
.if_data
, size
);
542 sf
= (xfs_attr_shortform_t
*)tmpbuffer
;
544 xfs_idata_realloc(dp
, -size
, XFS_ATTR_FORK
);
546 error
= xfs_da_grow_inode(args
, &blkno
);
549 * If we hit an IO error middle of the transaction inside
550 * grow_inode(), we may have inconsistent data. Bail out.
554 xfs_idata_realloc(dp
, size
, XFS_ATTR_FORK
); /* try to put */
555 memcpy(ifp
->if_u1
.if_data
, tmpbuffer
, size
); /* it back */
560 error
= xfs_attr_leaf_create(args
, blkno
, &bp
);
562 error
= xfs_da_shrink_inode(args
, 0, bp
);
566 xfs_idata_realloc(dp
, size
, XFS_ATTR_FORK
); /* try to put */
567 memcpy(ifp
->if_u1
.if_data
, tmpbuffer
, size
); /* it back */
571 memset((char *)&nargs
, 0, sizeof(nargs
));
573 nargs
.firstblock
= args
->firstblock
;
574 nargs
.flist
= args
->flist
;
575 nargs
.total
= args
->total
;
576 nargs
.whichfork
= XFS_ATTR_FORK
;
577 nargs
.trans
= args
->trans
;
578 nargs
.op_flags
= XFS_DA_OP_OKNOENT
;
581 for (i
= 0; i
< sf
->hdr
.count
; i
++) {
582 nargs
.name
= sfe
->nameval
;
583 nargs
.namelen
= sfe
->namelen
;
584 nargs
.value
= &sfe
->nameval
[nargs
.namelen
];
585 nargs
.valuelen
= sfe
->valuelen
;
586 nargs
.hashval
= xfs_da_hashname(sfe
->nameval
,
588 nargs
.flags
= XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe
->flags
);
589 error
= xfs_attr_leaf_lookup_int(bp
, &nargs
); /* set a->index */
590 ASSERT(error
== ENOATTR
);
591 error
= xfs_attr_leaf_add(bp
, &nargs
);
592 ASSERT(error
!= ENOSPC
);
595 sfe
= XFS_ATTR_SF_NEXTENTRY(sfe
);
600 kmem_free(tmpbuffer
);
605 xfs_attr_shortform_compare(const void *a
, const void *b
)
607 xfs_attr_sf_sort_t
*sa
, *sb
;
609 sa
= (xfs_attr_sf_sort_t
*)a
;
610 sb
= (xfs_attr_sf_sort_t
*)b
;
611 if (sa
->hash
< sb
->hash
) {
613 } else if (sa
->hash
> sb
->hash
) {
616 return(sa
->entno
- sb
->entno
);
621 #define XFS_ISRESET_CURSOR(cursor) \
622 (!((cursor)->initted) && !((cursor)->hashval) && \
623 !((cursor)->blkno) && !((cursor)->offset))
625 * Copy out entries of shortform attribute lists for attr_list().
626 * Shortform attribute lists are not stored in hashval sorted order.
627 * If the output buffer is not large enough to hold them all, then we
628 * we have to calculate each entries' hashvalue and sort them before
629 * we can begin returning them to the user.
633 xfs_attr_shortform_list(xfs_attr_list_context_t
*context
)
635 attrlist_cursor_kern_t
*cursor
;
636 xfs_attr_sf_sort_t
*sbuf
, *sbp
;
637 xfs_attr_shortform_t
*sf
;
638 xfs_attr_sf_entry_t
*sfe
;
640 int sbsize
, nsbuf
, count
, i
;
643 ASSERT(context
!= NULL
);
646 ASSERT(dp
->i_afp
!= NULL
);
647 sf
= (xfs_attr_shortform_t
*)dp
->i_afp
->if_u1
.if_data
;
651 cursor
= context
->cursor
;
652 ASSERT(cursor
!= NULL
);
654 trace_xfs_attr_list_sf(context
);
657 * If the buffer is large enough and the cursor is at the start,
658 * do not bother with sorting since we will return everything in
659 * one buffer and another call using the cursor won't need to be
661 * Note the generous fudge factor of 16 overhead bytes per entry.
662 * If bufsize is zero then put_listent must be a search function
663 * and can just scan through what we have.
665 if (context
->bufsize
== 0 ||
666 (XFS_ISRESET_CURSOR(cursor
) &&
667 (dp
->i_afp
->if_bytes
+ sf
->hdr
.count
* 16) < context
->bufsize
)) {
668 for (i
= 0, sfe
= &sf
->list
[0]; i
< sf
->hdr
.count
; i
++) {
669 error
= context
->put_listent(context
,
674 &sfe
->nameval
[sfe
->namelen
]);
677 * Either search callback finished early or
678 * didn't fit it all in the buffer after all.
680 if (context
->seen_enough
)
685 sfe
= XFS_ATTR_SF_NEXTENTRY(sfe
);
687 trace_xfs_attr_list_sf_all(context
);
691 /* do no more for a search callback */
692 if (context
->bufsize
== 0)
696 * It didn't all fit, so we have to sort everything on hashval.
698 sbsize
= sf
->hdr
.count
* sizeof(*sbuf
);
699 sbp
= sbuf
= kmem_alloc(sbsize
, KM_SLEEP
| KM_NOFS
);
702 * Scan the attribute list for the rest of the entries, storing
703 * the relevant info from only those that match into a buffer.
706 for (i
= 0, sfe
= &sf
->list
[0]; i
< sf
->hdr
.count
; i
++) {
708 ((char *)sfe
< (char *)sf
) ||
709 ((char *)sfe
>= ((char *)sf
+ dp
->i_afp
->if_bytes
)))) {
710 XFS_CORRUPTION_ERROR("xfs_attr_shortform_list",
712 context
->dp
->i_mount
, sfe
);
714 return XFS_ERROR(EFSCORRUPTED
);
718 sbp
->hash
= xfs_da_hashname(sfe
->nameval
, sfe
->namelen
);
719 sbp
->name
= sfe
->nameval
;
720 sbp
->namelen
= sfe
->namelen
;
721 /* These are bytes, and both on-disk, don't endian-flip */
722 sbp
->valuelen
= sfe
->valuelen
;
723 sbp
->flags
= sfe
->flags
;
724 sfe
= XFS_ATTR_SF_NEXTENTRY(sfe
);
730 * Sort the entries on hash then entno.
732 xfs_sort(sbuf
, nsbuf
, sizeof(*sbuf
), xfs_attr_shortform_compare
);
735 * Re-find our place IN THE SORTED LIST.
740 for (sbp
= sbuf
, i
= 0; i
< nsbuf
; i
++, sbp
++) {
741 if (sbp
->hash
== cursor
->hashval
) {
742 if (cursor
->offset
== count
) {
746 } else if (sbp
->hash
> cursor
->hashval
) {
756 * Loop putting entries into the user buffer.
758 for ( ; i
< nsbuf
; i
++, sbp
++) {
759 if (cursor
->hashval
!= sbp
->hash
) {
760 cursor
->hashval
= sbp
->hash
;
763 error
= context
->put_listent(context
,
768 &sbp
->name
[sbp
->namelen
]);
771 if (context
->seen_enough
)
781 * Check a leaf attribute block to see if all the entries would fit into
782 * a shortform attribute list.
785 xfs_attr_shortform_allfit(
787 struct xfs_inode
*dp
)
789 xfs_attr_leafblock_t
*leaf
;
790 xfs_attr_leaf_entry_t
*entry
;
791 xfs_attr_leaf_name_local_t
*name_loc
;
795 ASSERT(leaf
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
));
797 entry
= &leaf
->entries
[0];
798 bytes
= sizeof(struct xfs_attr_sf_hdr
);
799 for (i
= 0; i
< be16_to_cpu(leaf
->hdr
.count
); entry
++, i
++) {
800 if (entry
->flags
& XFS_ATTR_INCOMPLETE
)
801 continue; /* don't copy partial entries */
802 if (!(entry
->flags
& XFS_ATTR_LOCAL
))
804 name_loc
= xfs_attr_leaf_name_local(leaf
, i
);
805 if (name_loc
->namelen
>= XFS_ATTR_SF_ENTSIZE_MAX
)
807 if (be16_to_cpu(name_loc
->valuelen
) >= XFS_ATTR_SF_ENTSIZE_MAX
)
809 bytes
+= sizeof(struct xfs_attr_sf_entry
)-1
811 + be16_to_cpu(name_loc
->valuelen
);
813 if ((dp
->i_mount
->m_flags
& XFS_MOUNT_ATTR2
) &&
814 (dp
->i_d
.di_format
!= XFS_DINODE_FMT_BTREE
) &&
815 (bytes
== sizeof(struct xfs_attr_sf_hdr
)))
817 return(xfs_attr_shortform_bytesfit(dp
, bytes
));
821 * Convert a leaf attribute list to shortform attribute list
824 xfs_attr_leaf_to_shortform(
829 xfs_attr_leafblock_t
*leaf
;
830 xfs_attr_leaf_entry_t
*entry
;
831 xfs_attr_leaf_name_local_t
*name_loc
;
837 trace_xfs_attr_leaf_to_sf(args
);
840 tmpbuffer
= kmem_alloc(XFS_LBSIZE(dp
->i_mount
), KM_SLEEP
);
841 ASSERT(tmpbuffer
!= NULL
);
844 memcpy(tmpbuffer
, bp
->b_addr
, XFS_LBSIZE(dp
->i_mount
));
845 leaf
= (xfs_attr_leafblock_t
*)tmpbuffer
;
846 ASSERT(leaf
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
));
847 memset(bp
->b_addr
, 0, XFS_LBSIZE(dp
->i_mount
));
850 * Clean out the prior contents of the attribute list.
852 error
= xfs_da_shrink_inode(args
, 0, bp
);
857 ASSERT(dp
->i_mount
->m_flags
& XFS_MOUNT_ATTR2
);
858 ASSERT(dp
->i_d
.di_format
!= XFS_DINODE_FMT_BTREE
);
859 xfs_attr_fork_reset(dp
, args
->trans
);
863 xfs_attr_shortform_create(args
);
866 * Copy the attributes
868 memset((char *)&nargs
, 0, sizeof(nargs
));
870 nargs
.firstblock
= args
->firstblock
;
871 nargs
.flist
= args
->flist
;
872 nargs
.total
= args
->total
;
873 nargs
.whichfork
= XFS_ATTR_FORK
;
874 nargs
.trans
= args
->trans
;
875 nargs
.op_flags
= XFS_DA_OP_OKNOENT
;
876 entry
= &leaf
->entries
[0];
877 for (i
= 0; i
< be16_to_cpu(leaf
->hdr
.count
); entry
++, i
++) {
878 if (entry
->flags
& XFS_ATTR_INCOMPLETE
)
879 continue; /* don't copy partial entries */
882 ASSERT(entry
->flags
& XFS_ATTR_LOCAL
);
883 name_loc
= xfs_attr_leaf_name_local(leaf
, i
);
884 nargs
.name
= name_loc
->nameval
;
885 nargs
.namelen
= name_loc
->namelen
;
886 nargs
.value
= &name_loc
->nameval
[nargs
.namelen
];
887 nargs
.valuelen
= be16_to_cpu(name_loc
->valuelen
);
888 nargs
.hashval
= be32_to_cpu(entry
->hashval
);
889 nargs
.flags
= XFS_ATTR_NSP_ONDISK_TO_ARGS(entry
->flags
);
890 xfs_attr_shortform_add(&nargs
, forkoff
);
895 kmem_free(tmpbuffer
);
900 * Convert from using a single leaf to a root node and a leaf.
903 xfs_attr_leaf_to_node(xfs_da_args_t
*args
)
905 xfs_attr_leafblock_t
*leaf
;
906 xfs_da_intnode_t
*node
;
908 struct xfs_buf
*bp1
, *bp2
;
912 trace_xfs_attr_leaf_to_node(args
);
916 error
= xfs_da_grow_inode(args
, &blkno
);
919 error
= xfs_attr_leaf_read(args
->trans
, args
->dp
, 0, -1, &bp1
);
924 error
= xfs_da_get_buf(args
->trans
, args
->dp
, blkno
, -1, &bp2
,
928 bp2
->b_ops
= bp1
->b_ops
;
929 memcpy(bp2
->b_addr
, bp1
->b_addr
, XFS_LBSIZE(dp
->i_mount
));
931 xfs_trans_log_buf(args
->trans
, bp2
, 0, XFS_LBSIZE(dp
->i_mount
) - 1);
934 * Set up the new root node.
936 error
= xfs_da_node_create(args
, 0, 1, &bp1
, XFS_ATTR_FORK
);
941 ASSERT(leaf
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
));
942 /* both on-disk, don't endian-flip twice */
943 node
->btree
[0].hashval
=
944 leaf
->entries
[be16_to_cpu(leaf
->hdr
.count
)-1 ].hashval
;
945 node
->btree
[0].before
= cpu_to_be32(blkno
);
946 node
->hdr
.count
= cpu_to_be16(1);
947 xfs_trans_log_buf(args
->trans
, bp1
, 0, XFS_LBSIZE(dp
->i_mount
) - 1);
954 /*========================================================================
955 * Routines used for growing the Btree.
956 *========================================================================*/
959 * Create the initial contents of a leaf attribute list
960 * or a leaf in a node attribute list.
963 xfs_attr_leaf_create(
966 struct xfs_buf
**bpp
)
968 xfs_attr_leafblock_t
*leaf
;
969 xfs_attr_leaf_hdr_t
*hdr
;
974 trace_xfs_attr_leaf_create(args
);
978 error
= xfs_da_get_buf(args
->trans
, args
->dp
, blkno
, -1, &bp
,
982 bp
->b_ops
= &xfs_attr_leaf_buf_ops
;
984 memset((char *)leaf
, 0, XFS_LBSIZE(dp
->i_mount
));
986 hdr
->info
.magic
= cpu_to_be16(XFS_ATTR_LEAF_MAGIC
);
987 hdr
->firstused
= cpu_to_be16(XFS_LBSIZE(dp
->i_mount
));
988 if (!hdr
->firstused
) {
989 hdr
->firstused
= cpu_to_be16(
990 XFS_LBSIZE(dp
->i_mount
) - XFS_ATTR_LEAF_NAME_ALIGN
);
993 hdr
->freemap
[0].base
= cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t
));
994 hdr
->freemap
[0].size
= cpu_to_be16(be16_to_cpu(hdr
->firstused
) -
995 sizeof(xfs_attr_leaf_hdr_t
));
997 xfs_trans_log_buf(args
->trans
, bp
, 0, XFS_LBSIZE(dp
->i_mount
) - 1);
1004 * Split the leaf node, rebalance, then add the new entry.
1007 xfs_attr_leaf_split(xfs_da_state_t
*state
, xfs_da_state_blk_t
*oldblk
,
1008 xfs_da_state_blk_t
*newblk
)
1013 trace_xfs_attr_leaf_split(state
->args
);
1016 * Allocate space for a new leaf node.
1018 ASSERT(oldblk
->magic
== XFS_ATTR_LEAF_MAGIC
);
1019 error
= xfs_da_grow_inode(state
->args
, &blkno
);
1022 error
= xfs_attr_leaf_create(state
->args
, blkno
, &newblk
->bp
);
1025 newblk
->blkno
= blkno
;
1026 newblk
->magic
= XFS_ATTR_LEAF_MAGIC
;
1029 * Rebalance the entries across the two leaves.
1030 * NOTE: rebalance() currently depends on the 2nd block being empty.
1032 xfs_attr_leaf_rebalance(state
, oldblk
, newblk
);
1033 error
= xfs_da_blk_link(state
, oldblk
, newblk
);
1038 * Save info on "old" attribute for "atomic rename" ops, leaf_add()
1039 * modifies the index/blkno/rmtblk/rmtblkcnt fields to show the
1040 * "new" attrs info. Will need the "old" info to remove it later.
1042 * Insert the "new" entry in the correct block.
1044 if (state
->inleaf
) {
1045 trace_xfs_attr_leaf_add_old(state
->args
);
1046 error
= xfs_attr_leaf_add(oldblk
->bp
, state
->args
);
1048 trace_xfs_attr_leaf_add_new(state
->args
);
1049 error
= xfs_attr_leaf_add(newblk
->bp
, state
->args
);
1053 * Update last hashval in each block since we added the name.
1055 oldblk
->hashval
= xfs_attr_leaf_lasthash(oldblk
->bp
, NULL
);
1056 newblk
->hashval
= xfs_attr_leaf_lasthash(newblk
->bp
, NULL
);
1061 * Add a name to the leaf attribute list structure.
1066 struct xfs_da_args
*args
)
1068 xfs_attr_leafblock_t
*leaf
;
1069 xfs_attr_leaf_hdr_t
*hdr
;
1070 xfs_attr_leaf_map_t
*map
;
1071 int tablesize
, entsize
, sum
, tmp
, i
;
1073 trace_xfs_attr_leaf_add(args
);
1076 ASSERT(leaf
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
));
1077 ASSERT((args
->index
>= 0)
1078 && (args
->index
<= be16_to_cpu(leaf
->hdr
.count
)));
1080 entsize
= xfs_attr_leaf_newentsize(args
->namelen
, args
->valuelen
,
1081 args
->trans
->t_mountp
->m_sb
.sb_blocksize
, NULL
);
1084 * Search through freemap for first-fit on new name length.
1085 * (may need to figure in size of entry struct too)
1087 tablesize
= (be16_to_cpu(hdr
->count
) + 1)
1088 * sizeof(xfs_attr_leaf_entry_t
)
1089 + sizeof(xfs_attr_leaf_hdr_t
);
1090 map
= &hdr
->freemap
[XFS_ATTR_LEAF_MAPSIZE
-1];
1091 for (sum
= 0, i
= XFS_ATTR_LEAF_MAPSIZE
-1; i
>= 0; map
--, i
--) {
1092 if (tablesize
> be16_to_cpu(hdr
->firstused
)) {
1093 sum
+= be16_to_cpu(map
->size
);
1097 continue; /* no space in this map */
1099 if (be16_to_cpu(map
->base
) < be16_to_cpu(hdr
->firstused
))
1100 tmp
+= sizeof(xfs_attr_leaf_entry_t
);
1101 if (be16_to_cpu(map
->size
) >= tmp
) {
1102 tmp
= xfs_attr_leaf_add_work(bp
, args
, i
);
1105 sum
+= be16_to_cpu(map
->size
);
1109 * If there are no holes in the address space of the block,
1110 * and we don't have enough freespace, then compaction will do us
1111 * no good and we should just give up.
1113 if (!hdr
->holes
&& (sum
< entsize
))
1114 return(XFS_ERROR(ENOSPC
));
1117 * Compact the entries to coalesce free space.
1118 * This may change the hdr->count via dropping INCOMPLETE entries.
1120 xfs_attr_leaf_compact(args
, bp
);
1123 * After compaction, the block is guaranteed to have only one
1124 * free region, in freemap[0]. If it is not big enough, give up.
1126 if (be16_to_cpu(hdr
->freemap
[0].size
)
1127 < (entsize
+ sizeof(xfs_attr_leaf_entry_t
)))
1128 return(XFS_ERROR(ENOSPC
));
1130 return(xfs_attr_leaf_add_work(bp
, args
, 0));
1134 * Add a name to a leaf attribute list structure.
1137 xfs_attr_leaf_add_work(
1139 xfs_da_args_t
*args
,
1142 xfs_attr_leafblock_t
*leaf
;
1143 xfs_attr_leaf_hdr_t
*hdr
;
1144 xfs_attr_leaf_entry_t
*entry
;
1145 xfs_attr_leaf_name_local_t
*name_loc
;
1146 xfs_attr_leaf_name_remote_t
*name_rmt
;
1147 xfs_attr_leaf_map_t
*map
;
1151 trace_xfs_attr_leaf_add_work(args
);
1154 ASSERT(leaf
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
));
1156 ASSERT((mapindex
>= 0) && (mapindex
< XFS_ATTR_LEAF_MAPSIZE
));
1157 ASSERT((args
->index
>= 0) && (args
->index
<= be16_to_cpu(hdr
->count
)));
1160 * Force open some space in the entry array and fill it in.
1162 entry
= &leaf
->entries
[args
->index
];
1163 if (args
->index
< be16_to_cpu(hdr
->count
)) {
1164 tmp
= be16_to_cpu(hdr
->count
) - args
->index
;
1165 tmp
*= sizeof(xfs_attr_leaf_entry_t
);
1166 memmove((char *)(entry
+1), (char *)entry
, tmp
);
1167 xfs_trans_log_buf(args
->trans
, bp
,
1168 XFS_DA_LOGRANGE(leaf
, entry
, tmp
+ sizeof(*entry
)));
1170 be16_add_cpu(&hdr
->count
, 1);
1173 * Allocate space for the new string (at the end of the run).
1175 map
= &hdr
->freemap
[mapindex
];
1176 mp
= args
->trans
->t_mountp
;
1177 ASSERT(be16_to_cpu(map
->base
) < XFS_LBSIZE(mp
));
1178 ASSERT((be16_to_cpu(map
->base
) & 0x3) == 0);
1179 ASSERT(be16_to_cpu(map
->size
) >=
1180 xfs_attr_leaf_newentsize(args
->namelen
, args
->valuelen
,
1181 mp
->m_sb
.sb_blocksize
, NULL
));
1182 ASSERT(be16_to_cpu(map
->size
) < XFS_LBSIZE(mp
));
1183 ASSERT((be16_to_cpu(map
->size
) & 0x3) == 0);
1184 be16_add_cpu(&map
->size
,
1185 -xfs_attr_leaf_newentsize(args
->namelen
, args
->valuelen
,
1186 mp
->m_sb
.sb_blocksize
, &tmp
));
1187 entry
->nameidx
= cpu_to_be16(be16_to_cpu(map
->base
) +
1188 be16_to_cpu(map
->size
));
1189 entry
->hashval
= cpu_to_be32(args
->hashval
);
1190 entry
->flags
= tmp
? XFS_ATTR_LOCAL
: 0;
1191 entry
->flags
|= XFS_ATTR_NSP_ARGS_TO_ONDISK(args
->flags
);
1192 if (args
->op_flags
& XFS_DA_OP_RENAME
) {
1193 entry
->flags
|= XFS_ATTR_INCOMPLETE
;
1194 if ((args
->blkno2
== args
->blkno
) &&
1195 (args
->index2
<= args
->index
)) {
1199 xfs_trans_log_buf(args
->trans
, bp
,
1200 XFS_DA_LOGRANGE(leaf
, entry
, sizeof(*entry
)));
1201 ASSERT((args
->index
== 0) ||
1202 (be32_to_cpu(entry
->hashval
) >= be32_to_cpu((entry
-1)->hashval
)));
1203 ASSERT((args
->index
== be16_to_cpu(hdr
->count
)-1) ||
1204 (be32_to_cpu(entry
->hashval
) <= be32_to_cpu((entry
+1)->hashval
)));
1207 * For "remote" attribute values, simply note that we need to
1208 * allocate space for the "remote" value. We can't actually
1209 * allocate the extents in this transaction, and we can't decide
1210 * which blocks they should be as we might allocate more blocks
1211 * as part of this transaction (a split operation for example).
1213 if (entry
->flags
& XFS_ATTR_LOCAL
) {
1214 name_loc
= xfs_attr_leaf_name_local(leaf
, args
->index
);
1215 name_loc
->namelen
= args
->namelen
;
1216 name_loc
->valuelen
= cpu_to_be16(args
->valuelen
);
1217 memcpy((char *)name_loc
->nameval
, args
->name
, args
->namelen
);
1218 memcpy((char *)&name_loc
->nameval
[args
->namelen
], args
->value
,
1219 be16_to_cpu(name_loc
->valuelen
));
1221 name_rmt
= xfs_attr_leaf_name_remote(leaf
, args
->index
);
1222 name_rmt
->namelen
= args
->namelen
;
1223 memcpy((char *)name_rmt
->name
, args
->name
, args
->namelen
);
1224 entry
->flags
|= XFS_ATTR_INCOMPLETE
;
1226 name_rmt
->valuelen
= 0;
1227 name_rmt
->valueblk
= 0;
1229 args
->rmtblkcnt
= XFS_B_TO_FSB(mp
, args
->valuelen
);
1231 xfs_trans_log_buf(args
->trans
, bp
,
1232 XFS_DA_LOGRANGE(leaf
, xfs_attr_leaf_name(leaf
, args
->index
),
1233 xfs_attr_leaf_entsize(leaf
, args
->index
)));
1236 * Update the control info for this leaf node
1238 if (be16_to_cpu(entry
->nameidx
) < be16_to_cpu(hdr
->firstused
)) {
1239 /* both on-disk, don't endian-flip twice */
1240 hdr
->firstused
= entry
->nameidx
;
1242 ASSERT(be16_to_cpu(hdr
->firstused
) >=
1243 ((be16_to_cpu(hdr
->count
) * sizeof(*entry
)) + sizeof(*hdr
)));
1244 tmp
= (be16_to_cpu(hdr
->count
)-1) * sizeof(xfs_attr_leaf_entry_t
)
1245 + sizeof(xfs_attr_leaf_hdr_t
);
1246 map
= &hdr
->freemap
[0];
1247 for (i
= 0; i
< XFS_ATTR_LEAF_MAPSIZE
; map
++, i
++) {
1248 if (be16_to_cpu(map
->base
) == tmp
) {
1249 be16_add_cpu(&map
->base
, sizeof(xfs_attr_leaf_entry_t
));
1250 be16_add_cpu(&map
->size
,
1251 -((int)sizeof(xfs_attr_leaf_entry_t
)));
1254 be16_add_cpu(&hdr
->usedbytes
, xfs_attr_leaf_entsize(leaf
, args
->index
));
1255 xfs_trans_log_buf(args
->trans
, bp
,
1256 XFS_DA_LOGRANGE(leaf
, hdr
, sizeof(*hdr
)));
1261 * Garbage collect a leaf attribute list block by copying it to a new buffer.
1264 xfs_attr_leaf_compact(
1265 struct xfs_da_args
*args
,
1268 xfs_attr_leafblock_t
*leaf_s
, *leaf_d
;
1269 xfs_attr_leaf_hdr_t
*hdr_s
, *hdr_d
;
1270 struct xfs_trans
*trans
= args
->trans
;
1271 struct xfs_mount
*mp
= trans
->t_mountp
;
1274 trace_xfs_attr_leaf_compact(args
);
1276 tmpbuffer
= kmem_alloc(XFS_LBSIZE(mp
), KM_SLEEP
);
1277 ASSERT(tmpbuffer
!= NULL
);
1278 memcpy(tmpbuffer
, bp
->b_addr
, XFS_LBSIZE(mp
));
1279 memset(bp
->b_addr
, 0, XFS_LBSIZE(mp
));
1282 * Copy basic information
1284 leaf_s
= (xfs_attr_leafblock_t
*)tmpbuffer
;
1285 leaf_d
= bp
->b_addr
;
1286 hdr_s
= &leaf_s
->hdr
;
1287 hdr_d
= &leaf_d
->hdr
;
1288 hdr_d
->info
= hdr_s
->info
; /* struct copy */
1289 hdr_d
->firstused
= cpu_to_be16(XFS_LBSIZE(mp
));
1290 /* handle truncation gracefully */
1291 if (!hdr_d
->firstused
) {
1292 hdr_d
->firstused
= cpu_to_be16(
1293 XFS_LBSIZE(mp
) - XFS_ATTR_LEAF_NAME_ALIGN
);
1295 hdr_d
->usedbytes
= 0;
1298 hdr_d
->freemap
[0].base
= cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t
));
1299 hdr_d
->freemap
[0].size
= cpu_to_be16(be16_to_cpu(hdr_d
->firstused
) -
1300 sizeof(xfs_attr_leaf_hdr_t
));
1303 * Copy all entry's in the same (sorted) order,
1304 * but allocate name/value pairs packed and in sequence.
1306 xfs_attr_leaf_moveents(leaf_s
, 0, leaf_d
, 0,
1307 be16_to_cpu(hdr_s
->count
), mp
);
1308 xfs_trans_log_buf(trans
, bp
, 0, XFS_LBSIZE(mp
) - 1);
1310 kmem_free(tmpbuffer
);
1314 * Redistribute the attribute list entries between two leaf nodes,
1315 * taking into account the size of the new entry.
1317 * NOTE: if new block is empty, then it will get the upper half of the
1318 * old block. At present, all (one) callers pass in an empty second block.
1320 * This code adjusts the args->index/blkno and args->index2/blkno2 fields
1321 * to match what it is doing in splitting the attribute leaf block. Those
1322 * values are used in "atomic rename" operations on attributes. Note that
1323 * the "new" and "old" values can end up in different blocks.
1326 xfs_attr_leaf_rebalance(xfs_da_state_t
*state
, xfs_da_state_blk_t
*blk1
,
1327 xfs_da_state_blk_t
*blk2
)
1329 xfs_da_args_t
*args
;
1330 xfs_da_state_blk_t
*tmp_blk
;
1331 xfs_attr_leafblock_t
*leaf1
, *leaf2
;
1332 xfs_attr_leaf_hdr_t
*hdr1
, *hdr2
;
1333 int count
, totallen
, max
, space
, swap
;
1336 * Set up environment.
1338 ASSERT(blk1
->magic
== XFS_ATTR_LEAF_MAGIC
);
1339 ASSERT(blk2
->magic
== XFS_ATTR_LEAF_MAGIC
);
1340 leaf1
= blk1
->bp
->b_addr
;
1341 leaf2
= blk2
->bp
->b_addr
;
1342 ASSERT(leaf1
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
));
1343 ASSERT(leaf2
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
));
1344 ASSERT(leaf2
->hdr
.count
== 0);
1347 trace_xfs_attr_leaf_rebalance(args
);
1350 * Check ordering of blocks, reverse if it makes things simpler.
1352 * NOTE: Given that all (current) callers pass in an empty
1353 * second block, this code should never set "swap".
1356 if (xfs_attr_leaf_order(blk1
->bp
, blk2
->bp
)) {
1360 leaf1
= blk1
->bp
->b_addr
;
1361 leaf2
= blk2
->bp
->b_addr
;
1368 * Examine entries until we reduce the absolute difference in
1369 * byte usage between the two blocks to a minimum. Then get
1370 * the direction to copy and the number of elements to move.
1372 * "inleaf" is true if the new entry should be inserted into blk1.
1373 * If "swap" is also true, then reverse the sense of "inleaf".
1375 state
->inleaf
= xfs_attr_leaf_figure_balance(state
, blk1
, blk2
,
1378 state
->inleaf
= !state
->inleaf
;
1381 * Move any entries required from leaf to leaf:
1383 if (count
< be16_to_cpu(hdr1
->count
)) {
1385 * Figure the total bytes to be added to the destination leaf.
1387 /* number entries being moved */
1388 count
= be16_to_cpu(hdr1
->count
) - count
;
1389 space
= be16_to_cpu(hdr1
->usedbytes
) - totallen
;
1390 space
+= count
* sizeof(xfs_attr_leaf_entry_t
);
1393 * leaf2 is the destination, compact it if it looks tight.
1395 max
= be16_to_cpu(hdr2
->firstused
)
1396 - sizeof(xfs_attr_leaf_hdr_t
);
1397 max
-= be16_to_cpu(hdr2
->count
) * sizeof(xfs_attr_leaf_entry_t
);
1399 xfs_attr_leaf_compact(args
, blk2
->bp
);
1402 * Move high entries from leaf1 to low end of leaf2.
1404 xfs_attr_leaf_moveents(leaf1
, be16_to_cpu(hdr1
->count
) - count
,
1405 leaf2
, 0, count
, state
->mp
);
1407 xfs_trans_log_buf(args
->trans
, blk1
->bp
, 0, state
->blocksize
-1);
1408 xfs_trans_log_buf(args
->trans
, blk2
->bp
, 0, state
->blocksize
-1);
1409 } else if (count
> be16_to_cpu(hdr1
->count
)) {
1411 * I assert that since all callers pass in an empty
1412 * second buffer, this code should never execute.
1417 * Figure the total bytes to be added to the destination leaf.
1419 /* number entries being moved */
1420 count
-= be16_to_cpu(hdr1
->count
);
1421 space
= totallen
- be16_to_cpu(hdr1
->usedbytes
);
1422 space
+= count
* sizeof(xfs_attr_leaf_entry_t
);
1425 * leaf1 is the destination, compact it if it looks tight.
1427 max
= be16_to_cpu(hdr1
->firstused
)
1428 - sizeof(xfs_attr_leaf_hdr_t
);
1429 max
-= be16_to_cpu(hdr1
->count
) * sizeof(xfs_attr_leaf_entry_t
);
1431 xfs_attr_leaf_compact(args
, blk1
->bp
);
1434 * Move low entries from leaf2 to high end of leaf1.
1436 xfs_attr_leaf_moveents(leaf2
, 0, leaf1
,
1437 be16_to_cpu(hdr1
->count
), count
, state
->mp
);
1439 xfs_trans_log_buf(args
->trans
, blk1
->bp
, 0, state
->blocksize
-1);
1440 xfs_trans_log_buf(args
->trans
, blk2
->bp
, 0, state
->blocksize
-1);
1444 * Copy out last hashval in each block for B-tree code.
1446 blk1
->hashval
= be32_to_cpu(
1447 leaf1
->entries
[be16_to_cpu(leaf1
->hdr
.count
)-1].hashval
);
1448 blk2
->hashval
= be32_to_cpu(
1449 leaf2
->entries
[be16_to_cpu(leaf2
->hdr
.count
)-1].hashval
);
1452 * Adjust the expected index for insertion.
1453 * NOTE: this code depends on the (current) situation that the
1454 * second block was originally empty.
1456 * If the insertion point moved to the 2nd block, we must adjust
1457 * the index. We must also track the entry just following the
1458 * new entry for use in an "atomic rename" operation, that entry
1459 * is always the "old" entry and the "new" entry is what we are
1460 * inserting. The index/blkno fields refer to the "old" entry,
1461 * while the index2/blkno2 fields refer to the "new" entry.
1463 if (blk1
->index
> be16_to_cpu(leaf1
->hdr
.count
)) {
1464 ASSERT(state
->inleaf
== 0);
1465 blk2
->index
= blk1
->index
- be16_to_cpu(leaf1
->hdr
.count
);
1466 args
->index
= args
->index2
= blk2
->index
;
1467 args
->blkno
= args
->blkno2
= blk2
->blkno
;
1468 } else if (blk1
->index
== be16_to_cpu(leaf1
->hdr
.count
)) {
1469 if (state
->inleaf
) {
1470 args
->index
= blk1
->index
;
1471 args
->blkno
= blk1
->blkno
;
1473 args
->blkno2
= blk2
->blkno
;
1476 * On a double leaf split, the original attr location
1477 * is already stored in blkno2/index2, so don't
1478 * overwrite it overwise we corrupt the tree.
1480 blk2
->index
= blk1
->index
1481 - be16_to_cpu(leaf1
->hdr
.count
);
1482 args
->index
= blk2
->index
;
1483 args
->blkno
= blk2
->blkno
;
1484 if (!state
->extravalid
) {
1486 * set the new attr location to match the old
1487 * one and let the higher level split code
1488 * decide where in the leaf to place it.
1490 args
->index2
= blk2
->index
;
1491 args
->blkno2
= blk2
->blkno
;
1495 ASSERT(state
->inleaf
== 1);
1496 args
->index
= args
->index2
= blk1
->index
;
1497 args
->blkno
= args
->blkno2
= blk1
->blkno
;
1502 * Examine entries until we reduce the absolute difference in
1503 * byte usage between the two blocks to a minimum.
1504 * GROT: Is this really necessary? With other than a 512 byte blocksize,
1505 * GROT: there will always be enough room in either block for a new entry.
1506 * GROT: Do a double-split for this case?
1509 xfs_attr_leaf_figure_balance(xfs_da_state_t
*state
,
1510 xfs_da_state_blk_t
*blk1
,
1511 xfs_da_state_blk_t
*blk2
,
1512 int *countarg
, int *usedbytesarg
)
1514 xfs_attr_leafblock_t
*leaf1
, *leaf2
;
1515 xfs_attr_leaf_hdr_t
*hdr1
, *hdr2
;
1516 xfs_attr_leaf_entry_t
*entry
;
1517 int count
, max
, index
, totallen
, half
;
1518 int lastdelta
, foundit
, tmp
;
1521 * Set up environment.
1523 leaf1
= blk1
->bp
->b_addr
;
1524 leaf2
= blk2
->bp
->b_addr
;
1531 * Examine entries until we reduce the absolute difference in
1532 * byte usage between the two blocks to a minimum.
1534 max
= be16_to_cpu(hdr1
->count
) + be16_to_cpu(hdr2
->count
);
1535 half
= (max
+1) * sizeof(*entry
);
1536 half
+= be16_to_cpu(hdr1
->usedbytes
) +
1537 be16_to_cpu(hdr2
->usedbytes
) +
1538 xfs_attr_leaf_newentsize(
1539 state
->args
->namelen
,
1540 state
->args
->valuelen
,
1541 state
->blocksize
, NULL
);
1543 lastdelta
= state
->blocksize
;
1544 entry
= &leaf1
->entries
[0];
1545 for (count
= index
= 0; count
< max
; entry
++, index
++, count
++) {
1547 #define XFS_ATTR_ABS(A) (((A) < 0) ? -(A) : (A))
1549 * The new entry is in the first block, account for it.
1551 if (count
== blk1
->index
) {
1552 tmp
= totallen
+ sizeof(*entry
) +
1553 xfs_attr_leaf_newentsize(
1554 state
->args
->namelen
,
1555 state
->args
->valuelen
,
1556 state
->blocksize
, NULL
);
1557 if (XFS_ATTR_ABS(half
- tmp
) > lastdelta
)
1559 lastdelta
= XFS_ATTR_ABS(half
- tmp
);
1565 * Wrap around into the second block if necessary.
1567 if (count
== be16_to_cpu(hdr1
->count
)) {
1569 entry
= &leaf1
->entries
[0];
1574 * Figure out if next leaf entry would be too much.
1576 tmp
= totallen
+ sizeof(*entry
) + xfs_attr_leaf_entsize(leaf1
,
1578 if (XFS_ATTR_ABS(half
- tmp
) > lastdelta
)
1580 lastdelta
= XFS_ATTR_ABS(half
- tmp
);
1586 * Calculate the number of usedbytes that will end up in lower block.
1587 * If new entry not in lower block, fix up the count.
1589 totallen
-= count
* sizeof(*entry
);
1591 totallen
-= sizeof(*entry
) +
1592 xfs_attr_leaf_newentsize(
1593 state
->args
->namelen
,
1594 state
->args
->valuelen
,
1595 state
->blocksize
, NULL
);
1599 *usedbytesarg
= totallen
;
1603 /*========================================================================
1604 * Routines used for shrinking the Btree.
1605 *========================================================================*/
1608 * Check a leaf block and its neighbors to see if the block should be
1609 * collapsed into one or the other neighbor. Always keep the block
1610 * with the smaller block number.
1611 * If the current block is over 50% full, don't try to join it, return 0.
1612 * If the block is empty, fill in the state structure and return 2.
1613 * If it can be collapsed, fill in the state structure and return 1.
1614 * If nothing can be done, return 0.
1616 * GROT: allow for INCOMPLETE entries in calculation.
1619 xfs_attr_leaf_toosmall(xfs_da_state_t
*state
, int *action
)
1621 xfs_attr_leafblock_t
*leaf
;
1622 xfs_da_state_blk_t
*blk
;
1623 xfs_da_blkinfo_t
*info
;
1624 int count
, bytes
, forward
, error
, retval
, i
;
1628 trace_xfs_attr_leaf_toosmall(state
->args
);
1631 * Check for the degenerate case of the block being over 50% full.
1632 * If so, it's not worth even looking to see if we might be able
1633 * to coalesce with a sibling.
1635 blk
= &state
->path
.blk
[ state
->path
.active
-1 ];
1636 info
= blk
->bp
->b_addr
;
1637 ASSERT(info
->magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
));
1638 leaf
= (xfs_attr_leafblock_t
*)info
;
1639 count
= be16_to_cpu(leaf
->hdr
.count
);
1640 bytes
= sizeof(xfs_attr_leaf_hdr_t
) +
1641 count
* sizeof(xfs_attr_leaf_entry_t
) +
1642 be16_to_cpu(leaf
->hdr
.usedbytes
);
1643 if (bytes
> (state
->blocksize
>> 1)) {
1644 *action
= 0; /* blk over 50%, don't try to join */
1649 * Check for the degenerate case of the block being empty.
1650 * If the block is empty, we'll simply delete it, no need to
1651 * coalesce it with a sibling block. We choose (arbitrarily)
1652 * to merge with the forward block unless it is NULL.
1656 * Make altpath point to the block we want to keep and
1657 * path point to the block we want to drop (this one).
1659 forward
= (info
->forw
!= 0);
1660 memcpy(&state
->altpath
, &state
->path
, sizeof(state
->path
));
1661 error
= xfs_da_path_shift(state
, &state
->altpath
, forward
,
1674 * Examine each sibling block to see if we can coalesce with
1675 * at least 25% free space to spare. We need to figure out
1676 * whether to merge with the forward or the backward block.
1677 * We prefer coalescing with the lower numbered sibling so as
1678 * to shrink an attribute list over time.
1680 /* start with smaller blk num */
1681 forward
= (be32_to_cpu(info
->forw
) < be32_to_cpu(info
->back
));
1682 for (i
= 0; i
< 2; forward
= !forward
, i
++) {
1684 blkno
= be32_to_cpu(info
->forw
);
1686 blkno
= be32_to_cpu(info
->back
);
1689 error
= xfs_attr_leaf_read(state
->args
->trans
, state
->args
->dp
,
1694 leaf
= (xfs_attr_leafblock_t
*)info
;
1695 count
= be16_to_cpu(leaf
->hdr
.count
);
1696 bytes
= state
->blocksize
- (state
->blocksize
>>2);
1697 bytes
-= be16_to_cpu(leaf
->hdr
.usedbytes
);
1699 count
+= be16_to_cpu(leaf
->hdr
.count
);
1700 bytes
-= be16_to_cpu(leaf
->hdr
.usedbytes
);
1701 bytes
-= count
* sizeof(xfs_attr_leaf_entry_t
);
1702 bytes
-= sizeof(xfs_attr_leaf_hdr_t
);
1703 xfs_trans_brelse(state
->args
->trans
, bp
);
1705 break; /* fits with at least 25% to spare */
1713 * Make altpath point to the block we want to keep (the lower
1714 * numbered block) and path point to the block we want to drop.
1716 memcpy(&state
->altpath
, &state
->path
, sizeof(state
->path
));
1717 if (blkno
< blk
->blkno
) {
1718 error
= xfs_da_path_shift(state
, &state
->altpath
, forward
,
1721 error
= xfs_da_path_shift(state
, &state
->path
, forward
,
1735 * Remove a name from the leaf attribute list structure.
1737 * Return 1 if leaf is less than 37% full, 0 if >= 37% full.
1738 * If two leaves are 37% full, when combined they will leave 25% free.
1741 xfs_attr_leaf_remove(
1743 xfs_da_args_t
*args
)
1745 xfs_attr_leafblock_t
*leaf
;
1746 xfs_attr_leaf_hdr_t
*hdr
;
1747 xfs_attr_leaf_map_t
*map
;
1748 xfs_attr_leaf_entry_t
*entry
;
1749 int before
, after
, smallest
, entsize
;
1750 int tablesize
, tmp
, i
;
1753 trace_xfs_attr_leaf_remove(args
);
1756 ASSERT(leaf
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
));
1758 mp
= args
->trans
->t_mountp
;
1759 ASSERT((be16_to_cpu(hdr
->count
) > 0)
1760 && (be16_to_cpu(hdr
->count
) < (XFS_LBSIZE(mp
)/8)));
1761 ASSERT((args
->index
>= 0)
1762 && (args
->index
< be16_to_cpu(hdr
->count
)));
1763 ASSERT(be16_to_cpu(hdr
->firstused
) >=
1764 ((be16_to_cpu(hdr
->count
) * sizeof(*entry
)) + sizeof(*hdr
)));
1765 entry
= &leaf
->entries
[args
->index
];
1766 ASSERT(be16_to_cpu(entry
->nameidx
) >= be16_to_cpu(hdr
->firstused
));
1767 ASSERT(be16_to_cpu(entry
->nameidx
) < XFS_LBSIZE(mp
));
1770 * Scan through free region table:
1771 * check for adjacency of free'd entry with an existing one,
1772 * find smallest free region in case we need to replace it,
1773 * adjust any map that borders the entry table,
1775 tablesize
= be16_to_cpu(hdr
->count
) * sizeof(xfs_attr_leaf_entry_t
)
1776 + sizeof(xfs_attr_leaf_hdr_t
);
1777 map
= &hdr
->freemap
[0];
1778 tmp
= be16_to_cpu(map
->size
);
1779 before
= after
= -1;
1780 smallest
= XFS_ATTR_LEAF_MAPSIZE
- 1;
1781 entsize
= xfs_attr_leaf_entsize(leaf
, args
->index
);
1782 for (i
= 0; i
< XFS_ATTR_LEAF_MAPSIZE
; map
++, i
++) {
1783 ASSERT(be16_to_cpu(map
->base
) < XFS_LBSIZE(mp
));
1784 ASSERT(be16_to_cpu(map
->size
) < XFS_LBSIZE(mp
));
1785 if (be16_to_cpu(map
->base
) == tablesize
) {
1786 be16_add_cpu(&map
->base
,
1787 -((int)sizeof(xfs_attr_leaf_entry_t
)));
1788 be16_add_cpu(&map
->size
, sizeof(xfs_attr_leaf_entry_t
));
1791 if ((be16_to_cpu(map
->base
) + be16_to_cpu(map
->size
))
1792 == be16_to_cpu(entry
->nameidx
)) {
1794 } else if (be16_to_cpu(map
->base
)
1795 == (be16_to_cpu(entry
->nameidx
) + entsize
)) {
1797 } else if (be16_to_cpu(map
->size
) < tmp
) {
1798 tmp
= be16_to_cpu(map
->size
);
1804 * Coalesce adjacent freemap regions,
1805 * or replace the smallest region.
1807 if ((before
>= 0) || (after
>= 0)) {
1808 if ((before
>= 0) && (after
>= 0)) {
1809 map
= &hdr
->freemap
[before
];
1810 be16_add_cpu(&map
->size
, entsize
);
1811 be16_add_cpu(&map
->size
,
1812 be16_to_cpu(hdr
->freemap
[after
].size
));
1813 hdr
->freemap
[after
].base
= 0;
1814 hdr
->freemap
[after
].size
= 0;
1815 } else if (before
>= 0) {
1816 map
= &hdr
->freemap
[before
];
1817 be16_add_cpu(&map
->size
, entsize
);
1819 map
= &hdr
->freemap
[after
];
1820 /* both on-disk, don't endian flip twice */
1821 map
->base
= entry
->nameidx
;
1822 be16_add_cpu(&map
->size
, entsize
);
1826 * Replace smallest region (if it is smaller than free'd entry)
1828 map
= &hdr
->freemap
[smallest
];
1829 if (be16_to_cpu(map
->size
) < entsize
) {
1830 map
->base
= cpu_to_be16(be16_to_cpu(entry
->nameidx
));
1831 map
->size
= cpu_to_be16(entsize
);
1836 * Did we remove the first entry?
1838 if (be16_to_cpu(entry
->nameidx
) == be16_to_cpu(hdr
->firstused
))
1844 * Compress the remaining entries and zero out the removed stuff.
1846 memset(xfs_attr_leaf_name(leaf
, args
->index
), 0, entsize
);
1847 be16_add_cpu(&hdr
->usedbytes
, -entsize
);
1848 xfs_trans_log_buf(args
->trans
, bp
,
1849 XFS_DA_LOGRANGE(leaf
, xfs_attr_leaf_name(leaf
, args
->index
),
1852 tmp
= (be16_to_cpu(hdr
->count
) - args
->index
)
1853 * sizeof(xfs_attr_leaf_entry_t
);
1854 memmove((char *)entry
, (char *)(entry
+1), tmp
);
1855 be16_add_cpu(&hdr
->count
, -1);
1856 xfs_trans_log_buf(args
->trans
, bp
,
1857 XFS_DA_LOGRANGE(leaf
, entry
, tmp
+ sizeof(*entry
)));
1858 entry
= &leaf
->entries
[be16_to_cpu(hdr
->count
)];
1859 memset((char *)entry
, 0, sizeof(xfs_attr_leaf_entry_t
));
1862 * If we removed the first entry, re-find the first used byte
1863 * in the name area. Note that if the entry was the "firstused",
1864 * then we don't have a "hole" in our block resulting from
1865 * removing the name.
1868 tmp
= XFS_LBSIZE(mp
);
1869 entry
= &leaf
->entries
[0];
1870 for (i
= be16_to_cpu(hdr
->count
)-1; i
>= 0; entry
++, i
--) {
1871 ASSERT(be16_to_cpu(entry
->nameidx
) >=
1872 be16_to_cpu(hdr
->firstused
));
1873 ASSERT(be16_to_cpu(entry
->nameidx
) < XFS_LBSIZE(mp
));
1875 if (be16_to_cpu(entry
->nameidx
) < tmp
)
1876 tmp
= be16_to_cpu(entry
->nameidx
);
1878 hdr
->firstused
= cpu_to_be16(tmp
);
1879 if (!hdr
->firstused
) {
1880 hdr
->firstused
= cpu_to_be16(
1881 tmp
- XFS_ATTR_LEAF_NAME_ALIGN
);
1884 hdr
->holes
= 1; /* mark as needing compaction */
1886 xfs_trans_log_buf(args
->trans
, bp
,
1887 XFS_DA_LOGRANGE(leaf
, hdr
, sizeof(*hdr
)));
1890 * Check if leaf is less than 50% full, caller may want to
1891 * "join" the leaf with a sibling if so.
1893 tmp
= sizeof(xfs_attr_leaf_hdr_t
);
1894 tmp
+= be16_to_cpu(leaf
->hdr
.count
) * sizeof(xfs_attr_leaf_entry_t
);
1895 tmp
+= be16_to_cpu(leaf
->hdr
.usedbytes
);
1896 return(tmp
< mp
->m_attr_magicpct
); /* leaf is < 37% full */
1900 * Move all the attribute list entries from drop_leaf into save_leaf.
1903 xfs_attr_leaf_unbalance(xfs_da_state_t
*state
, xfs_da_state_blk_t
*drop_blk
,
1904 xfs_da_state_blk_t
*save_blk
)
1906 xfs_attr_leafblock_t
*drop_leaf
, *save_leaf
, *tmp_leaf
;
1907 xfs_attr_leaf_hdr_t
*drop_hdr
, *save_hdr
, *tmp_hdr
;
1911 trace_xfs_attr_leaf_unbalance(state
->args
);
1914 * Set up environment.
1917 ASSERT(drop_blk
->magic
== XFS_ATTR_LEAF_MAGIC
);
1918 ASSERT(save_blk
->magic
== XFS_ATTR_LEAF_MAGIC
);
1919 drop_leaf
= drop_blk
->bp
->b_addr
;
1920 save_leaf
= save_blk
->bp
->b_addr
;
1921 ASSERT(drop_leaf
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
));
1922 ASSERT(save_leaf
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
));
1923 drop_hdr
= &drop_leaf
->hdr
;
1924 save_hdr
= &save_leaf
->hdr
;
1927 * Save last hashval from dying block for later Btree fixup.
1929 drop_blk
->hashval
= be32_to_cpu(
1930 drop_leaf
->entries
[be16_to_cpu(drop_leaf
->hdr
.count
)-1].hashval
);
1933 * Check if we need a temp buffer, or can we do it in place.
1934 * Note that we don't check "leaf" for holes because we will
1935 * always be dropping it, toosmall() decided that for us already.
1937 if (save_hdr
->holes
== 0) {
1939 * dest leaf has no holes, so we add there. May need
1940 * to make some room in the entry array.
1942 if (xfs_attr_leaf_order(save_blk
->bp
, drop_blk
->bp
)) {
1943 xfs_attr_leaf_moveents(drop_leaf
, 0, save_leaf
, 0,
1944 be16_to_cpu(drop_hdr
->count
), mp
);
1946 xfs_attr_leaf_moveents(drop_leaf
, 0, save_leaf
,
1947 be16_to_cpu(save_hdr
->count
),
1948 be16_to_cpu(drop_hdr
->count
), mp
);
1952 * Destination has holes, so we make a temporary copy
1953 * of the leaf and add them both to that.
1955 tmpbuffer
= kmem_alloc(state
->blocksize
, KM_SLEEP
);
1956 ASSERT(tmpbuffer
!= NULL
);
1957 memset(tmpbuffer
, 0, state
->blocksize
);
1958 tmp_leaf
= (xfs_attr_leafblock_t
*)tmpbuffer
;
1959 tmp_hdr
= &tmp_leaf
->hdr
;
1960 tmp_hdr
->info
= save_hdr
->info
; /* struct copy */
1962 tmp_hdr
->firstused
= cpu_to_be16(state
->blocksize
);
1963 if (!tmp_hdr
->firstused
) {
1964 tmp_hdr
->firstused
= cpu_to_be16(
1965 state
->blocksize
- XFS_ATTR_LEAF_NAME_ALIGN
);
1967 tmp_hdr
->usedbytes
= 0;
1968 if (xfs_attr_leaf_order(save_blk
->bp
, drop_blk
->bp
)) {
1969 xfs_attr_leaf_moveents(drop_leaf
, 0, tmp_leaf
, 0,
1970 be16_to_cpu(drop_hdr
->count
), mp
);
1971 xfs_attr_leaf_moveents(save_leaf
, 0, tmp_leaf
,
1972 be16_to_cpu(tmp_leaf
->hdr
.count
),
1973 be16_to_cpu(save_hdr
->count
), mp
);
1975 xfs_attr_leaf_moveents(save_leaf
, 0, tmp_leaf
, 0,
1976 be16_to_cpu(save_hdr
->count
), mp
);
1977 xfs_attr_leaf_moveents(drop_leaf
, 0, tmp_leaf
,
1978 be16_to_cpu(tmp_leaf
->hdr
.count
),
1979 be16_to_cpu(drop_hdr
->count
), mp
);
1981 memcpy((char *)save_leaf
, (char *)tmp_leaf
, state
->blocksize
);
1982 kmem_free(tmpbuffer
);
1985 xfs_trans_log_buf(state
->args
->trans
, save_blk
->bp
, 0,
1986 state
->blocksize
- 1);
1989 * Copy out last hashval in each block for B-tree code.
1991 save_blk
->hashval
= be32_to_cpu(
1992 save_leaf
->entries
[be16_to_cpu(save_leaf
->hdr
.count
)-1].hashval
);
1995 /*========================================================================
1996 * Routines used for finding things in the Btree.
1997 *========================================================================*/
2000 * Look up a name in a leaf attribute list structure.
2001 * This is the internal routine, it uses the caller's buffer.
2003 * Note that duplicate keys are allowed, but only check within the
2004 * current leaf node. The Btree code must check in adjacent leaf nodes.
2006 * Return in args->index the index into the entry[] array of either
2007 * the found entry, or where the entry should have been (insert before
2010 * Don't change the args->value unless we find the attribute.
2013 xfs_attr_leaf_lookup_int(
2015 xfs_da_args_t
*args
)
2017 xfs_attr_leafblock_t
*leaf
;
2018 xfs_attr_leaf_entry_t
*entry
;
2019 xfs_attr_leaf_name_local_t
*name_loc
;
2020 xfs_attr_leaf_name_remote_t
*name_rmt
;
2022 xfs_dahash_t hashval
;
2024 trace_xfs_attr_leaf_lookup(args
);
2027 ASSERT(leaf
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
));
2028 ASSERT(be16_to_cpu(leaf
->hdr
.count
)
2029 < (XFS_LBSIZE(args
->dp
->i_mount
)/8));
2032 * Binary search. (note: small blocks will skip this loop)
2034 hashval
= args
->hashval
;
2035 probe
= span
= be16_to_cpu(leaf
->hdr
.count
) / 2;
2036 for (entry
= &leaf
->entries
[probe
]; span
> 4;
2037 entry
= &leaf
->entries
[probe
]) {
2039 if (be32_to_cpu(entry
->hashval
) < hashval
)
2041 else if (be32_to_cpu(entry
->hashval
) > hashval
)
2046 ASSERT((probe
>= 0) &&
2048 || (probe
< be16_to_cpu(leaf
->hdr
.count
))));
2049 ASSERT((span
<= 4) || (be32_to_cpu(entry
->hashval
) == hashval
));
2052 * Since we may have duplicate hashval's, find the first matching
2053 * hashval in the leaf.
2055 while ((probe
> 0) && (be32_to_cpu(entry
->hashval
) >= hashval
)) {
2059 while ((probe
< be16_to_cpu(leaf
->hdr
.count
)) &&
2060 (be32_to_cpu(entry
->hashval
) < hashval
)) {
2064 if ((probe
== be16_to_cpu(leaf
->hdr
.count
)) ||
2065 (be32_to_cpu(entry
->hashval
) != hashval
)) {
2066 args
->index
= probe
;
2067 return(XFS_ERROR(ENOATTR
));
2071 * Duplicate keys may be present, so search all of them for a match.
2073 for ( ; (probe
< be16_to_cpu(leaf
->hdr
.count
)) &&
2074 (be32_to_cpu(entry
->hashval
) == hashval
);
2077 * GROT: Add code to remove incomplete entries.
2080 * If we are looking for INCOMPLETE entries, show only those.
2081 * If we are looking for complete entries, show only those.
2083 if ((args
->flags
& XFS_ATTR_INCOMPLETE
) !=
2084 (entry
->flags
& XFS_ATTR_INCOMPLETE
)) {
2087 if (entry
->flags
& XFS_ATTR_LOCAL
) {
2088 name_loc
= xfs_attr_leaf_name_local(leaf
, probe
);
2089 if (name_loc
->namelen
!= args
->namelen
)
2091 if (memcmp(args
->name
, (char *)name_loc
->nameval
, args
->namelen
) != 0)
2093 if (!xfs_attr_namesp_match(args
->flags
, entry
->flags
))
2095 args
->index
= probe
;
2096 return(XFS_ERROR(EEXIST
));
2098 name_rmt
= xfs_attr_leaf_name_remote(leaf
, probe
);
2099 if (name_rmt
->namelen
!= args
->namelen
)
2101 if (memcmp(args
->name
, (char *)name_rmt
->name
,
2102 args
->namelen
) != 0)
2104 if (!xfs_attr_namesp_match(args
->flags
, entry
->flags
))
2106 args
->index
= probe
;
2107 args
->rmtblkno
= be32_to_cpu(name_rmt
->valueblk
);
2108 args
->rmtblkcnt
= XFS_B_TO_FSB(args
->dp
->i_mount
,
2109 be32_to_cpu(name_rmt
->valuelen
));
2110 return(XFS_ERROR(EEXIST
));
2113 args
->index
= probe
;
2114 return(XFS_ERROR(ENOATTR
));
2118 * Get the value associated with an attribute name from a leaf attribute
2122 xfs_attr_leaf_getvalue(
2124 xfs_da_args_t
*args
)
2127 xfs_attr_leafblock_t
*leaf
;
2128 xfs_attr_leaf_entry_t
*entry
;
2129 xfs_attr_leaf_name_local_t
*name_loc
;
2130 xfs_attr_leaf_name_remote_t
*name_rmt
;
2133 ASSERT(leaf
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
));
2134 ASSERT(be16_to_cpu(leaf
->hdr
.count
)
2135 < (XFS_LBSIZE(args
->dp
->i_mount
)/8));
2136 ASSERT(args
->index
< be16_to_cpu(leaf
->hdr
.count
));
2138 entry
= &leaf
->entries
[args
->index
];
2139 if (entry
->flags
& XFS_ATTR_LOCAL
) {
2140 name_loc
= xfs_attr_leaf_name_local(leaf
, args
->index
);
2141 ASSERT(name_loc
->namelen
== args
->namelen
);
2142 ASSERT(memcmp(args
->name
, name_loc
->nameval
, args
->namelen
) == 0);
2143 valuelen
= be16_to_cpu(name_loc
->valuelen
);
2144 if (args
->flags
& ATTR_KERNOVAL
) {
2145 args
->valuelen
= valuelen
;
2148 if (args
->valuelen
< valuelen
) {
2149 args
->valuelen
= valuelen
;
2150 return(XFS_ERROR(ERANGE
));
2152 args
->valuelen
= valuelen
;
2153 memcpy(args
->value
, &name_loc
->nameval
[args
->namelen
], valuelen
);
2155 name_rmt
= xfs_attr_leaf_name_remote(leaf
, args
->index
);
2156 ASSERT(name_rmt
->namelen
== args
->namelen
);
2157 ASSERT(memcmp(args
->name
, name_rmt
->name
, args
->namelen
) == 0);
2158 valuelen
= be32_to_cpu(name_rmt
->valuelen
);
2159 args
->rmtblkno
= be32_to_cpu(name_rmt
->valueblk
);
2160 args
->rmtblkcnt
= XFS_B_TO_FSB(args
->dp
->i_mount
, valuelen
);
2161 if (args
->flags
& ATTR_KERNOVAL
) {
2162 args
->valuelen
= valuelen
;
2165 if (args
->valuelen
< valuelen
) {
2166 args
->valuelen
= valuelen
;
2167 return(XFS_ERROR(ERANGE
));
2169 args
->valuelen
= valuelen
;
2174 /*========================================================================
2176 *========================================================================*/
2179 * Move the indicated entries from one leaf to another.
2180 * NOTE: this routine modifies both source and destination leaves.
2184 xfs_attr_leaf_moveents(xfs_attr_leafblock_t
*leaf_s
, int start_s
,
2185 xfs_attr_leafblock_t
*leaf_d
, int start_d
,
2186 int count
, xfs_mount_t
*mp
)
2188 xfs_attr_leaf_hdr_t
*hdr_s
, *hdr_d
;
2189 xfs_attr_leaf_entry_t
*entry_s
, *entry_d
;
2193 * Check for nothing to do.
2199 * Set up environment.
2201 ASSERT(leaf_s
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
));
2202 ASSERT(leaf_d
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
));
2203 hdr_s
= &leaf_s
->hdr
;
2204 hdr_d
= &leaf_d
->hdr
;
2205 ASSERT((be16_to_cpu(hdr_s
->count
) > 0) &&
2206 (be16_to_cpu(hdr_s
->count
) < (XFS_LBSIZE(mp
)/8)));
2207 ASSERT(be16_to_cpu(hdr_s
->firstused
) >=
2208 ((be16_to_cpu(hdr_s
->count
)
2209 * sizeof(*entry_s
))+sizeof(*hdr_s
)));
2210 ASSERT(be16_to_cpu(hdr_d
->count
) < (XFS_LBSIZE(mp
)/8));
2211 ASSERT(be16_to_cpu(hdr_d
->firstused
) >=
2212 ((be16_to_cpu(hdr_d
->count
)
2213 * sizeof(*entry_d
))+sizeof(*hdr_d
)));
2215 ASSERT(start_s
< be16_to_cpu(hdr_s
->count
));
2216 ASSERT(start_d
<= be16_to_cpu(hdr_d
->count
));
2217 ASSERT(count
<= be16_to_cpu(hdr_s
->count
));
2220 * Move the entries in the destination leaf up to make a hole?
2222 if (start_d
< be16_to_cpu(hdr_d
->count
)) {
2223 tmp
= be16_to_cpu(hdr_d
->count
) - start_d
;
2224 tmp
*= sizeof(xfs_attr_leaf_entry_t
);
2225 entry_s
= &leaf_d
->entries
[start_d
];
2226 entry_d
= &leaf_d
->entries
[start_d
+ count
];
2227 memmove((char *)entry_d
, (char *)entry_s
, tmp
);
2231 * Copy all entry's in the same (sorted) order,
2232 * but allocate attribute info packed and in sequence.
2234 entry_s
= &leaf_s
->entries
[start_s
];
2235 entry_d
= &leaf_d
->entries
[start_d
];
2237 for (i
= 0; i
< count
; entry_s
++, entry_d
++, desti
++, i
++) {
2238 ASSERT(be16_to_cpu(entry_s
->nameidx
)
2239 >= be16_to_cpu(hdr_s
->firstused
));
2240 tmp
= xfs_attr_leaf_entsize(leaf_s
, start_s
+ i
);
2243 * Code to drop INCOMPLETE entries. Difficult to use as we
2244 * may also need to change the insertion index. Code turned
2245 * off for 6.2, should be revisited later.
2247 if (entry_s
->flags
& XFS_ATTR_INCOMPLETE
) { /* skip partials? */
2248 memset(xfs_attr_leaf_name(leaf_s
, start_s
+ i
), 0, tmp
);
2249 be16_add_cpu(&hdr_s
->usedbytes
, -tmp
);
2250 be16_add_cpu(&hdr_s
->count
, -1);
2251 entry_d
--; /* to compensate for ++ in loop hdr */
2253 if ((start_s
+ i
) < offset
)
2254 result
++; /* insertion index adjustment */
2257 be16_add_cpu(&hdr_d
->firstused
, -tmp
);
2258 /* both on-disk, don't endian flip twice */
2259 entry_d
->hashval
= entry_s
->hashval
;
2260 /* both on-disk, don't endian flip twice */
2261 entry_d
->nameidx
= hdr_d
->firstused
;
2262 entry_d
->flags
= entry_s
->flags
;
2263 ASSERT(be16_to_cpu(entry_d
->nameidx
) + tmp
2265 memmove(xfs_attr_leaf_name(leaf_d
, desti
),
2266 xfs_attr_leaf_name(leaf_s
, start_s
+ i
), tmp
);
2267 ASSERT(be16_to_cpu(entry_s
->nameidx
) + tmp
2269 memset(xfs_attr_leaf_name(leaf_s
, start_s
+ i
), 0, tmp
);
2270 be16_add_cpu(&hdr_s
->usedbytes
, -tmp
);
2271 be16_add_cpu(&hdr_d
->usedbytes
, tmp
);
2272 be16_add_cpu(&hdr_s
->count
, -1);
2273 be16_add_cpu(&hdr_d
->count
, 1);
2274 tmp
= be16_to_cpu(hdr_d
->count
)
2275 * sizeof(xfs_attr_leaf_entry_t
)
2276 + sizeof(xfs_attr_leaf_hdr_t
);
2277 ASSERT(be16_to_cpu(hdr_d
->firstused
) >= tmp
);
2284 * Zero out the entries we just copied.
2286 if (start_s
== be16_to_cpu(hdr_s
->count
)) {
2287 tmp
= count
* sizeof(xfs_attr_leaf_entry_t
);
2288 entry_s
= &leaf_s
->entries
[start_s
];
2289 ASSERT(((char *)entry_s
+ tmp
) <=
2290 ((char *)leaf_s
+ XFS_LBSIZE(mp
)));
2291 memset((char *)entry_s
, 0, tmp
);
2294 * Move the remaining entries down to fill the hole,
2295 * then zero the entries at the top.
2297 tmp
= be16_to_cpu(hdr_s
->count
) - count
;
2298 tmp
*= sizeof(xfs_attr_leaf_entry_t
);
2299 entry_s
= &leaf_s
->entries
[start_s
+ count
];
2300 entry_d
= &leaf_s
->entries
[start_s
];
2301 memmove((char *)entry_d
, (char *)entry_s
, tmp
);
2303 tmp
= count
* sizeof(xfs_attr_leaf_entry_t
);
2304 entry_s
= &leaf_s
->entries
[be16_to_cpu(hdr_s
->count
)];
2305 ASSERT(((char *)entry_s
+ tmp
) <=
2306 ((char *)leaf_s
+ XFS_LBSIZE(mp
)));
2307 memset((char *)entry_s
, 0, tmp
);
2311 * Fill in the freemap information
2313 hdr_d
->freemap
[0].base
= cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t
));
2314 be16_add_cpu(&hdr_d
->freemap
[0].base
, be16_to_cpu(hdr_d
->count
) *
2315 sizeof(xfs_attr_leaf_entry_t
));
2316 hdr_d
->freemap
[0].size
= cpu_to_be16(be16_to_cpu(hdr_d
->firstused
)
2317 - be16_to_cpu(hdr_d
->freemap
[0].base
));
2318 hdr_d
->freemap
[1].base
= 0;
2319 hdr_d
->freemap
[2].base
= 0;
2320 hdr_d
->freemap
[1].size
= 0;
2321 hdr_d
->freemap
[2].size
= 0;
2322 hdr_s
->holes
= 1; /* leaf may not be compact */
2326 * Compare two leaf blocks "order".
2327 * Return 0 unless leaf2 should go before leaf1.
2330 xfs_attr_leaf_order(
2331 struct xfs_buf
*leaf1_bp
,
2332 struct xfs_buf
*leaf2_bp
)
2334 xfs_attr_leafblock_t
*leaf1
, *leaf2
;
2336 leaf1
= leaf1_bp
->b_addr
;
2337 leaf2
= leaf2_bp
->b_addr
;
2338 ASSERT((leaf1
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
)) &&
2339 (leaf2
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
)));
2340 if ((be16_to_cpu(leaf1
->hdr
.count
) > 0) &&
2341 (be16_to_cpu(leaf2
->hdr
.count
) > 0) &&
2342 ((be32_to_cpu(leaf2
->entries
[0].hashval
) <
2343 be32_to_cpu(leaf1
->entries
[0].hashval
)) ||
2344 (be32_to_cpu(leaf2
->entries
[
2345 be16_to_cpu(leaf2
->hdr
.count
)-1].hashval
) <
2346 be32_to_cpu(leaf1
->entries
[
2347 be16_to_cpu(leaf1
->hdr
.count
)-1].hashval
)))) {
2354 * Pick up the last hashvalue from a leaf block.
2357 xfs_attr_leaf_lasthash(
2361 xfs_attr_leafblock_t
*leaf
;
2364 ASSERT(leaf
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
));
2366 *count
= be16_to_cpu(leaf
->hdr
.count
);
2367 if (!leaf
->hdr
.count
)
2369 return be32_to_cpu(leaf
->entries
[be16_to_cpu(leaf
->hdr
.count
)-1].hashval
);
2373 * Calculate the number of bytes used to store the indicated attribute
2374 * (whether local or remote only calculate bytes in this block).
2377 xfs_attr_leaf_entsize(xfs_attr_leafblock_t
*leaf
, int index
)
2379 xfs_attr_leaf_name_local_t
*name_loc
;
2380 xfs_attr_leaf_name_remote_t
*name_rmt
;
2383 ASSERT(leaf
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
));
2384 if (leaf
->entries
[index
].flags
& XFS_ATTR_LOCAL
) {
2385 name_loc
= xfs_attr_leaf_name_local(leaf
, index
);
2386 size
= xfs_attr_leaf_entsize_local(name_loc
->namelen
,
2387 be16_to_cpu(name_loc
->valuelen
));
2389 name_rmt
= xfs_attr_leaf_name_remote(leaf
, index
);
2390 size
= xfs_attr_leaf_entsize_remote(name_rmt
->namelen
);
2396 * Calculate the number of bytes that would be required to store the new
2397 * attribute (whether local or remote only calculate bytes in this block).
2398 * This routine decides as a side effect whether the attribute will be
2399 * a "local" or a "remote" attribute.
2402 xfs_attr_leaf_newentsize(int namelen
, int valuelen
, int blocksize
, int *local
)
2406 size
= xfs_attr_leaf_entsize_local(namelen
, valuelen
);
2407 if (size
< xfs_attr_leaf_entsize_local_max(blocksize
)) {
2412 size
= xfs_attr_leaf_entsize_remote(namelen
);
2421 * Copy out attribute list entries for attr_list(), for leaf attribute lists.
2424 xfs_attr_leaf_list_int(
2426 xfs_attr_list_context_t
*context
)
2428 attrlist_cursor_kern_t
*cursor
;
2429 xfs_attr_leafblock_t
*leaf
;
2430 xfs_attr_leaf_entry_t
*entry
;
2435 cursor
= context
->cursor
;
2436 cursor
->initted
= 1;
2438 trace_xfs_attr_list_leaf(context
);
2441 * Re-find our place in the leaf block if this is a new syscall.
2443 if (context
->resynch
) {
2444 entry
= &leaf
->entries
[0];
2445 for (i
= 0; i
< be16_to_cpu(leaf
->hdr
.count
); entry
++, i
++) {
2446 if (be32_to_cpu(entry
->hashval
) == cursor
->hashval
) {
2447 if (cursor
->offset
== context
->dupcnt
) {
2448 context
->dupcnt
= 0;
2452 } else if (be32_to_cpu(entry
->hashval
) >
2454 context
->dupcnt
= 0;
2458 if (i
== be16_to_cpu(leaf
->hdr
.count
)) {
2459 trace_xfs_attr_list_notfound(context
);
2463 entry
= &leaf
->entries
[0];
2466 context
->resynch
= 0;
2469 * We have found our place, start copying out the new attributes.
2472 for ( ; (i
< be16_to_cpu(leaf
->hdr
.count
)); entry
++, i
++) {
2473 if (be32_to_cpu(entry
->hashval
) != cursor
->hashval
) {
2474 cursor
->hashval
= be32_to_cpu(entry
->hashval
);
2478 if (entry
->flags
& XFS_ATTR_INCOMPLETE
)
2479 continue; /* skip incomplete entries */
2481 if (entry
->flags
& XFS_ATTR_LOCAL
) {
2482 xfs_attr_leaf_name_local_t
*name_loc
=
2483 xfs_attr_leaf_name_local(leaf
, i
);
2485 retval
= context
->put_listent(context
,
2488 (int)name_loc
->namelen
,
2489 be16_to_cpu(name_loc
->valuelen
),
2490 &name_loc
->nameval
[name_loc
->namelen
]);
2494 xfs_attr_leaf_name_remote_t
*name_rmt
=
2495 xfs_attr_leaf_name_remote(leaf
, i
);
2497 int valuelen
= be32_to_cpu(name_rmt
->valuelen
);
2499 if (context
->put_value
) {
2502 memset((char *)&args
, 0, sizeof(args
));
2503 args
.dp
= context
->dp
;
2504 args
.whichfork
= XFS_ATTR_FORK
;
2505 args
.valuelen
= valuelen
;
2506 args
.value
= kmem_alloc(valuelen
, KM_SLEEP
| KM_NOFS
);
2507 args
.rmtblkno
= be32_to_cpu(name_rmt
->valueblk
);
2508 args
.rmtblkcnt
= XFS_B_TO_FSB(args
.dp
->i_mount
, valuelen
);
2509 retval
= xfs_attr_rmtval_get(&args
);
2512 retval
= context
->put_listent(context
,
2515 (int)name_rmt
->namelen
,
2518 kmem_free(args
.value
);
2520 retval
= context
->put_listent(context
,
2523 (int)name_rmt
->namelen
,
2530 if (context
->seen_enough
)
2534 trace_xfs_attr_list_leaf_end(context
);
2539 /*========================================================================
2540 * Manage the INCOMPLETE flag in a leaf entry
2541 *========================================================================*/
2544 * Clear the INCOMPLETE flag on an entry in a leaf block.
2547 xfs_attr_leaf_clearflag(xfs_da_args_t
*args
)
2549 xfs_attr_leafblock_t
*leaf
;
2550 xfs_attr_leaf_entry_t
*entry
;
2551 xfs_attr_leaf_name_remote_t
*name_rmt
;
2555 xfs_attr_leaf_name_local_t
*name_loc
;
2560 trace_xfs_attr_leaf_clearflag(args
);
2562 * Set up the operation.
2564 error
= xfs_attr_leaf_read(args
->trans
, args
->dp
, args
->blkno
, -1, &bp
);
2569 ASSERT(args
->index
< be16_to_cpu(leaf
->hdr
.count
));
2570 ASSERT(args
->index
>= 0);
2571 entry
= &leaf
->entries
[ args
->index
];
2572 ASSERT(entry
->flags
& XFS_ATTR_INCOMPLETE
);
2575 if (entry
->flags
& XFS_ATTR_LOCAL
) {
2576 name_loc
= xfs_attr_leaf_name_local(leaf
, args
->index
);
2577 namelen
= name_loc
->namelen
;
2578 name
= (char *)name_loc
->nameval
;
2580 name_rmt
= xfs_attr_leaf_name_remote(leaf
, args
->index
);
2581 namelen
= name_rmt
->namelen
;
2582 name
= (char *)name_rmt
->name
;
2584 ASSERT(be32_to_cpu(entry
->hashval
) == args
->hashval
);
2585 ASSERT(namelen
== args
->namelen
);
2586 ASSERT(memcmp(name
, args
->name
, namelen
) == 0);
2589 entry
->flags
&= ~XFS_ATTR_INCOMPLETE
;
2590 xfs_trans_log_buf(args
->trans
, bp
,
2591 XFS_DA_LOGRANGE(leaf
, entry
, sizeof(*entry
)));
2593 if (args
->rmtblkno
) {
2594 ASSERT((entry
->flags
& XFS_ATTR_LOCAL
) == 0);
2595 name_rmt
= xfs_attr_leaf_name_remote(leaf
, args
->index
);
2596 name_rmt
->valueblk
= cpu_to_be32(args
->rmtblkno
);
2597 name_rmt
->valuelen
= cpu_to_be32(args
->valuelen
);
2598 xfs_trans_log_buf(args
->trans
, bp
,
2599 XFS_DA_LOGRANGE(leaf
, name_rmt
, sizeof(*name_rmt
)));
2603 * Commit the flag value change and start the next trans in series.
2605 return xfs_trans_roll(&args
->trans
, args
->dp
);
2609 * Set the INCOMPLETE flag on an entry in a leaf block.
2612 xfs_attr_leaf_setflag(xfs_da_args_t
*args
)
2614 xfs_attr_leafblock_t
*leaf
;
2615 xfs_attr_leaf_entry_t
*entry
;
2616 xfs_attr_leaf_name_remote_t
*name_rmt
;
2620 trace_xfs_attr_leaf_setflag(args
);
2623 * Set up the operation.
2625 error
= xfs_attr_leaf_read(args
->trans
, args
->dp
, args
->blkno
, -1, &bp
);
2630 ASSERT(args
->index
< be16_to_cpu(leaf
->hdr
.count
));
2631 ASSERT(args
->index
>= 0);
2632 entry
= &leaf
->entries
[ args
->index
];
2634 ASSERT((entry
->flags
& XFS_ATTR_INCOMPLETE
) == 0);
2635 entry
->flags
|= XFS_ATTR_INCOMPLETE
;
2636 xfs_trans_log_buf(args
->trans
, bp
,
2637 XFS_DA_LOGRANGE(leaf
, entry
, sizeof(*entry
)));
2638 if ((entry
->flags
& XFS_ATTR_LOCAL
) == 0) {
2639 name_rmt
= xfs_attr_leaf_name_remote(leaf
, args
->index
);
2640 name_rmt
->valueblk
= 0;
2641 name_rmt
->valuelen
= 0;
2642 xfs_trans_log_buf(args
->trans
, bp
,
2643 XFS_DA_LOGRANGE(leaf
, name_rmt
, sizeof(*name_rmt
)));
2647 * Commit the flag value change and start the next trans in series.
2649 return xfs_trans_roll(&args
->trans
, args
->dp
);
2653 * In a single transaction, clear the INCOMPLETE flag on the leaf entry
2654 * given by args->blkno/index and set the INCOMPLETE flag on the leaf
2655 * entry given by args->blkno2/index2.
2657 * Note that they could be in different blocks, or in the same block.
2660 xfs_attr_leaf_flipflags(xfs_da_args_t
*args
)
2662 xfs_attr_leafblock_t
*leaf1
, *leaf2
;
2663 xfs_attr_leaf_entry_t
*entry1
, *entry2
;
2664 xfs_attr_leaf_name_remote_t
*name_rmt
;
2665 struct xfs_buf
*bp1
, *bp2
;
2668 xfs_attr_leaf_name_local_t
*name_loc
;
2669 int namelen1
, namelen2
;
2670 char *name1
, *name2
;
2673 trace_xfs_attr_leaf_flipflags(args
);
2676 * Read the block containing the "old" attr
2678 error
= xfs_attr_leaf_read(args
->trans
, args
->dp
, args
->blkno
, -1, &bp1
);
2683 * Read the block containing the "new" attr, if it is different
2685 if (args
->blkno2
!= args
->blkno
) {
2686 error
= xfs_attr_leaf_read(args
->trans
, args
->dp
, args
->blkno2
,
2694 leaf1
= bp1
->b_addr
;
2695 ASSERT(args
->index
< be16_to_cpu(leaf1
->hdr
.count
));
2696 ASSERT(args
->index
>= 0);
2697 entry1
= &leaf1
->entries
[ args
->index
];
2699 leaf2
= bp2
->b_addr
;
2700 ASSERT(args
->index2
< be16_to_cpu(leaf2
->hdr
.count
));
2701 ASSERT(args
->index2
>= 0);
2702 entry2
= &leaf2
->entries
[ args
->index2
];
2705 if (entry1
->flags
& XFS_ATTR_LOCAL
) {
2706 name_loc
= xfs_attr_leaf_name_local(leaf1
, args
->index
);
2707 namelen1
= name_loc
->namelen
;
2708 name1
= (char *)name_loc
->nameval
;
2710 name_rmt
= xfs_attr_leaf_name_remote(leaf1
, args
->index
);
2711 namelen1
= name_rmt
->namelen
;
2712 name1
= (char *)name_rmt
->name
;
2714 if (entry2
->flags
& XFS_ATTR_LOCAL
) {
2715 name_loc
= xfs_attr_leaf_name_local(leaf2
, args
->index2
);
2716 namelen2
= name_loc
->namelen
;
2717 name2
= (char *)name_loc
->nameval
;
2719 name_rmt
= xfs_attr_leaf_name_remote(leaf2
, args
->index2
);
2720 namelen2
= name_rmt
->namelen
;
2721 name2
= (char *)name_rmt
->name
;
2723 ASSERT(be32_to_cpu(entry1
->hashval
) == be32_to_cpu(entry2
->hashval
));
2724 ASSERT(namelen1
== namelen2
);
2725 ASSERT(memcmp(name1
, name2
, namelen1
) == 0);
2728 ASSERT(entry1
->flags
& XFS_ATTR_INCOMPLETE
);
2729 ASSERT((entry2
->flags
& XFS_ATTR_INCOMPLETE
) == 0);
2731 entry1
->flags
&= ~XFS_ATTR_INCOMPLETE
;
2732 xfs_trans_log_buf(args
->trans
, bp1
,
2733 XFS_DA_LOGRANGE(leaf1
, entry1
, sizeof(*entry1
)));
2734 if (args
->rmtblkno
) {
2735 ASSERT((entry1
->flags
& XFS_ATTR_LOCAL
) == 0);
2736 name_rmt
= xfs_attr_leaf_name_remote(leaf1
, args
->index
);
2737 name_rmt
->valueblk
= cpu_to_be32(args
->rmtblkno
);
2738 name_rmt
->valuelen
= cpu_to_be32(args
->valuelen
);
2739 xfs_trans_log_buf(args
->trans
, bp1
,
2740 XFS_DA_LOGRANGE(leaf1
, name_rmt
, sizeof(*name_rmt
)));
2743 entry2
->flags
|= XFS_ATTR_INCOMPLETE
;
2744 xfs_trans_log_buf(args
->trans
, bp2
,
2745 XFS_DA_LOGRANGE(leaf2
, entry2
, sizeof(*entry2
)));
2746 if ((entry2
->flags
& XFS_ATTR_LOCAL
) == 0) {
2747 name_rmt
= xfs_attr_leaf_name_remote(leaf2
, args
->index2
);
2748 name_rmt
->valueblk
= 0;
2749 name_rmt
->valuelen
= 0;
2750 xfs_trans_log_buf(args
->trans
, bp2
,
2751 XFS_DA_LOGRANGE(leaf2
, name_rmt
, sizeof(*name_rmt
)));
2755 * Commit the flag value change and start the next trans in series.
2757 error
= xfs_trans_roll(&args
->trans
, args
->dp
);
2762 /*========================================================================
2763 * Indiscriminately delete the entire attribute fork
2764 *========================================================================*/
2767 * Recurse (gasp!) through the attribute nodes until we find leaves.
2768 * We're doing a depth-first traversal in order to invalidate everything.
2771 xfs_attr_root_inactive(xfs_trans_t
**trans
, xfs_inode_t
*dp
)
2773 xfs_da_blkinfo_t
*info
;
2779 * Read block 0 to see what we have to work with.
2780 * We only get here if we have extents, since we remove
2781 * the extents in reverse order the extent containing
2782 * block 0 must still be there.
2784 error
= xfs_da_node_read(*trans
, dp
, 0, -1, &bp
, XFS_ATTR_FORK
);
2787 blkno
= XFS_BUF_ADDR(bp
);
2790 * Invalidate the tree, even if the "tree" is only a single leaf block.
2791 * This is a depth-first traversal!
2794 if (info
->magic
== cpu_to_be16(XFS_DA_NODE_MAGIC
)) {
2795 error
= xfs_attr_node_inactive(trans
, dp
, bp
, 1);
2796 } else if (info
->magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
)) {
2797 error
= xfs_attr_leaf_inactive(trans
, dp
, bp
);
2799 error
= XFS_ERROR(EIO
);
2800 xfs_trans_brelse(*trans
, bp
);
2806 * Invalidate the incore copy of the root block.
2808 error
= xfs_da_get_buf(*trans
, dp
, 0, blkno
, &bp
, XFS_ATTR_FORK
);
2811 xfs_trans_binval(*trans
, bp
); /* remove from cache */
2813 * Commit the invalidate and start the next transaction.
2815 error
= xfs_trans_roll(trans
, dp
);
2821 * Recurse (gasp!) through the attribute nodes until we find leaves.
2822 * We're doing a depth-first traversal in order to invalidate everything.
2825 xfs_attr_node_inactive(
2826 struct xfs_trans
**trans
,
2827 struct xfs_inode
*dp
,
2831 xfs_da_blkinfo_t
*info
;
2832 xfs_da_intnode_t
*node
;
2833 xfs_dablk_t child_fsb
;
2834 xfs_daddr_t parent_blkno
, child_blkno
;
2835 int error
, count
, i
;
2836 struct xfs_buf
*child_bp
;
2839 * Since this code is recursive (gasp!) we must protect ourselves.
2841 if (level
> XFS_DA_NODE_MAXDEPTH
) {
2842 xfs_trans_brelse(*trans
, bp
); /* no locks for later trans */
2843 return(XFS_ERROR(EIO
));
2847 ASSERT(node
->hdr
.info
.magic
== cpu_to_be16(XFS_DA_NODE_MAGIC
));
2848 parent_blkno
= XFS_BUF_ADDR(bp
); /* save for re-read later */
2849 count
= be16_to_cpu(node
->hdr
.count
);
2851 xfs_trans_brelse(*trans
, bp
);
2854 child_fsb
= be32_to_cpu(node
->btree
[0].before
);
2855 xfs_trans_brelse(*trans
, bp
); /* no locks for later trans */
2858 * If this is the node level just above the leaves, simply loop
2859 * over the leaves removing all of them. If this is higher up
2860 * in the tree, recurse downward.
2862 for (i
= 0; i
< count
; i
++) {
2864 * Read the subsidiary block to see what we have to work with.
2865 * Don't do this in a transaction. This is a depth-first
2866 * traversal of the tree so we may deal with many blocks
2867 * before we come back to this one.
2869 error
= xfs_da_node_read(*trans
, dp
, child_fsb
, -2, &child_bp
,
2874 /* save for re-read later */
2875 child_blkno
= XFS_BUF_ADDR(child_bp
);
2878 * Invalidate the subtree, however we have to.
2880 info
= child_bp
->b_addr
;
2881 if (info
->magic
== cpu_to_be16(XFS_DA_NODE_MAGIC
)) {
2882 error
= xfs_attr_node_inactive(trans
, dp
,
2884 } else if (info
->magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
)) {
2885 error
= xfs_attr_leaf_inactive(trans
, dp
,
2888 error
= XFS_ERROR(EIO
);
2889 xfs_trans_brelse(*trans
, child_bp
);
2895 * Remove the subsidiary block from the cache
2898 error
= xfs_da_get_buf(*trans
, dp
, 0, child_blkno
,
2899 &child_bp
, XFS_ATTR_FORK
);
2902 xfs_trans_binval(*trans
, child_bp
);
2906 * If we're not done, re-read the parent to get the next
2907 * child block number.
2909 if ((i
+1) < count
) {
2910 error
= xfs_da_node_read(*trans
, dp
, 0, parent_blkno
,
2911 &bp
, XFS_ATTR_FORK
);
2914 child_fsb
= be32_to_cpu(node
->btree
[i
+1].before
);
2915 xfs_trans_brelse(*trans
, bp
);
2918 * Atomically commit the whole invalidate stuff.
2920 error
= xfs_trans_roll(trans
, dp
);
2929 * Invalidate all of the "remote" value regions pointed to by a particular
2931 * Note that we must release the lock on the buffer so that we are not
2932 * caught holding something that the logging code wants to flush to disk.
2935 xfs_attr_leaf_inactive(
2936 struct xfs_trans
**trans
,
2937 struct xfs_inode
*dp
,
2940 xfs_attr_leafblock_t
*leaf
;
2941 xfs_attr_leaf_entry_t
*entry
;
2942 xfs_attr_leaf_name_remote_t
*name_rmt
;
2943 xfs_attr_inactive_list_t
*list
, *lp
;
2944 int error
, count
, size
, tmp
, i
;
2947 ASSERT(leaf
->hdr
.info
.magic
== cpu_to_be16(XFS_ATTR_LEAF_MAGIC
));
2950 * Count the number of "remote" value extents.
2953 entry
= &leaf
->entries
[0];
2954 for (i
= 0; i
< be16_to_cpu(leaf
->hdr
.count
); entry
++, i
++) {
2955 if (be16_to_cpu(entry
->nameidx
) &&
2956 ((entry
->flags
& XFS_ATTR_LOCAL
) == 0)) {
2957 name_rmt
= xfs_attr_leaf_name_remote(leaf
, i
);
2958 if (name_rmt
->valueblk
)
2964 * If there are no "remote" values, we're done.
2967 xfs_trans_brelse(*trans
, bp
);
2972 * Allocate storage for a list of all the "remote" value extents.
2974 size
= count
* sizeof(xfs_attr_inactive_list_t
);
2975 list
= (xfs_attr_inactive_list_t
*)kmem_alloc(size
, KM_SLEEP
);
2978 * Identify each of the "remote" value extents.
2981 entry
= &leaf
->entries
[0];
2982 for (i
= 0; i
< be16_to_cpu(leaf
->hdr
.count
); entry
++, i
++) {
2983 if (be16_to_cpu(entry
->nameidx
) &&
2984 ((entry
->flags
& XFS_ATTR_LOCAL
) == 0)) {
2985 name_rmt
= xfs_attr_leaf_name_remote(leaf
, i
);
2986 if (name_rmt
->valueblk
) {
2987 lp
->valueblk
= be32_to_cpu(name_rmt
->valueblk
);
2988 lp
->valuelen
= XFS_B_TO_FSB(dp
->i_mount
,
2989 be32_to_cpu(name_rmt
->valuelen
));
2994 xfs_trans_brelse(*trans
, bp
); /* unlock for trans. in freextent() */
2997 * Invalidate each of the "remote" value extents.
3000 for (lp
= list
, i
= 0; i
< count
; i
++, lp
++) {
3001 tmp
= xfs_attr_leaf_freextent(trans
, dp
,
3002 lp
->valueblk
, lp
->valuelen
);
3005 error
= tmp
; /* save only the 1st errno */
3008 kmem_free((xfs_caddr_t
)list
);
3013 * Look at all the extents for this logical region,
3014 * invalidate any buffers that are incore/in transactions.
3017 xfs_attr_leaf_freextent(xfs_trans_t
**trans
, xfs_inode_t
*dp
,
3018 xfs_dablk_t blkno
, int blkcnt
)
3020 xfs_bmbt_irec_t map
;
3022 int tblkcnt
, dblkcnt
, nmap
, error
;
3027 * Roll through the "value", invalidating the attribute value's
3032 while (tblkcnt
> 0) {
3034 * Try to remember where we decided to put the value.
3037 error
= xfs_bmapi_read(dp
, (xfs_fileoff_t
)tblkno
, tblkcnt
,
3038 &map
, &nmap
, XFS_BMAPI_ATTRFORK
);
3043 ASSERT(map
.br_startblock
!= DELAYSTARTBLOCK
);
3046 * If it's a hole, these are already unmapped
3047 * so there's nothing to invalidate.
3049 if (map
.br_startblock
!= HOLESTARTBLOCK
) {
3051 dblkno
= XFS_FSB_TO_DADDR(dp
->i_mount
,
3053 dblkcnt
= XFS_FSB_TO_BB(dp
->i_mount
,
3055 bp
= xfs_trans_get_buf(*trans
,
3056 dp
->i_mount
->m_ddev_targp
,
3057 dblkno
, dblkcnt
, 0);
3060 xfs_trans_binval(*trans
, bp
);
3062 * Roll to next transaction.
3064 error
= xfs_trans_roll(trans
, dp
);
3069 tblkno
+= map
.br_blockcount
;
3070 tblkcnt
-= map
.br_blockcount
;