Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.2 2980 lines 86 kB view raw
1/* 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 3 * All Rights Reserved. 4 * 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. 8 * 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. 13 * 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 17 */ 18#include "xfs.h" 19#include "xfs_fs.h" 20#include "xfs_types.h" 21#include "xfs_bit.h" 22#include "xfs_log.h" 23#include "xfs_inum.h" 24#include "xfs_trans.h" 25#include "xfs_sb.h" 26#include "xfs_ag.h" 27#include "xfs_mount.h" 28#include "xfs_da_btree.h" 29#include "xfs_bmap_btree.h" 30#include "xfs_alloc_btree.h" 31#include "xfs_ialloc_btree.h" 32#include "xfs_alloc.h" 33#include "xfs_btree.h" 34#include "xfs_attr_sf.h" 35#include "xfs_dinode.h" 36#include "xfs_inode.h" 37#include "xfs_inode_item.h" 38#include "xfs_bmap.h" 39#include "xfs_attr.h" 40#include "xfs_attr_leaf.h" 41#include "xfs_error.h" 42#include "xfs_trace.h" 43 44/* 45 * xfs_attr_leaf.c 46 * 47 * Routines to implement leaf blocks of attributes as Btrees of hashed names. 48 */ 49 50/*======================================================================== 51 * Function prototypes for the kernel. 52 *========================================================================*/ 53 54/* 55 * Routines used for growing the Btree. 56 */ 57STATIC int xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t which_block, 58 xfs_dabuf_t **bpp); 59STATIC int xfs_attr_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args, 60 int freemap_index); 61STATIC void xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer); 62STATIC void xfs_attr_leaf_rebalance(xfs_da_state_t *state, 63 xfs_da_state_blk_t *blk1, 64 xfs_da_state_blk_t *blk2); 65STATIC 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); 70 71/* 72 * Routines used for shrinking the Btree. 73 */ 74STATIC int xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, 75 xfs_dabuf_t *bp, int level); 76STATIC int xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, 77 xfs_dabuf_t *bp); 78STATIC int xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp, 79 xfs_dablk_t blkno, int blkcnt); 80 81/* 82 * Utility routines. 83 */ 84STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf, 85 int src_start, 86 xfs_attr_leafblock_t *dst_leaf, 87 int dst_start, int move_count, 88 xfs_mount_t *mp); 89STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); 90 91/*======================================================================== 92 * Namespace helper routines 93 *========================================================================*/ 94 95/* 96 * If namespace bits don't match return 0. 97 * If all match then return 1. 98 */ 99STATIC int 100xfs_attr_namesp_match(int arg_flags, int ondisk_flags) 101{ 102 return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags); 103} 104 105 106/*======================================================================== 107 * External routines when attribute fork size < XFS_LITINO(mp). 108 *========================================================================*/ 109 110/* 111 * Query whether the requested number of additional bytes of extended 112 * attribute space will be able to fit inline. 113 * 114 * Returns zero if not, else the di_forkoff fork offset to be used in the 115 * literal area for attribute data once the new bytes have been added. 116 * 117 * di_forkoff must be 8 byte aligned, hence is stored as a >>3 value; 118 * special case for dev/uuid inodes, they have fixed size data forks. 119 */ 120int 121xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes) 122{ 123 int offset; 124 int minforkoff; /* lower limit on valid forkoff locations */ 125 int maxforkoff; /* upper limit on valid forkoff locations */ 126 int dsize; 127 xfs_mount_t *mp = dp->i_mount; 128 129 offset = (XFS_LITINO(mp) - bytes) >> 3; /* rounded down */ 130 131 switch (dp->i_d.di_format) { 132 case XFS_DINODE_FMT_DEV: 133 minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; 134 return (offset >= minforkoff) ? minforkoff : 0; 135 case XFS_DINODE_FMT_UUID: 136 minforkoff = roundup(sizeof(uuid_t), 8) >> 3; 137 return (offset >= minforkoff) ? minforkoff : 0; 138 } 139 140 /* 141 * If the requested numbers of bytes is smaller or equal to the 142 * current attribute fork size we can always proceed. 143 * 144 * Note that if_bytes in the data fork might actually be larger than 145 * the current data fork size is due to delalloc extents. In that 146 * case either the extent count will go down when they are converted 147 * to real extents, or the delalloc conversion will take care of the 148 * literal area rebalancing. 149 */ 150 if (bytes <= XFS_IFORK_ASIZE(dp)) 151 return dp->i_d.di_forkoff; 152 153 /* 154 * For attr2 we can try to move the forkoff if there is space in the 155 * literal area, but for the old format we are done if there is no 156 * space in the fixed attribute fork. 157 */ 158 if (!(mp->m_flags & XFS_MOUNT_ATTR2)) 159 return 0; 160 161 dsize = dp->i_df.if_bytes; 162 163 switch (dp->i_d.di_format) { 164 case XFS_DINODE_FMT_EXTENTS: 165 /* 166 * If there is no attr fork and the data fork is extents, 167 * determine if creating the default attr fork will result 168 * in the extents form migrating to btree. If so, the 169 * minimum offset only needs to be the space required for 170 * the btree root. 171 */ 172 if (!dp->i_d.di_forkoff && dp->i_df.if_bytes > 173 xfs_default_attroffset(dp)) 174 dsize = XFS_BMDR_SPACE_CALC(MINDBTPTRS); 175 break; 176 case XFS_DINODE_FMT_BTREE: 177 /* 178 * If we have a data btree then keep forkoff if we have one, 179 * otherwise we are adding a new attr, so then we set 180 * minforkoff to where the btree root can finish so we have 181 * plenty of room for attrs 182 */ 183 if (dp->i_d.di_forkoff) { 184 if (offset < dp->i_d.di_forkoff) 185 return 0; 186 return dp->i_d.di_forkoff; 187 } 188 dsize = XFS_BMAP_BROOT_SPACE(dp->i_df.if_broot); 189 break; 190 } 191 192 /* 193 * A data fork btree root must have space for at least 194 * MINDBTPTRS key/ptr pairs if the data fork is small or empty. 195 */ 196 minforkoff = MAX(dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS)); 197 minforkoff = roundup(minforkoff, 8) >> 3; 198 199 /* attr fork btree root can have at least this many key/ptr pairs */ 200 maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS); 201 maxforkoff = maxforkoff >> 3; /* rounded down */ 202 203 if (offset >= maxforkoff) 204 return maxforkoff; 205 if (offset >= minforkoff) 206 return offset; 207 return 0; 208} 209 210/* 211 * Switch on the ATTR2 superblock bit (implies also FEATURES2) 212 */ 213STATIC void 214xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp) 215{ 216 if ((mp->m_flags & XFS_MOUNT_ATTR2) && 217 !(xfs_sb_version_hasattr2(&mp->m_sb))) { 218 spin_lock(&mp->m_sb_lock); 219 if (!xfs_sb_version_hasattr2(&mp->m_sb)) { 220 xfs_sb_version_addattr2(&mp->m_sb); 221 spin_unlock(&mp->m_sb_lock); 222 xfs_mod_sb(tp, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); 223 } else 224 spin_unlock(&mp->m_sb_lock); 225 } 226} 227 228/* 229 * Create the initial contents of a shortform attribute list. 230 */ 231void 232xfs_attr_shortform_create(xfs_da_args_t *args) 233{ 234 xfs_attr_sf_hdr_t *hdr; 235 xfs_inode_t *dp; 236 xfs_ifork_t *ifp; 237 238 dp = args->dp; 239 ASSERT(dp != NULL); 240 ifp = dp->i_afp; 241 ASSERT(ifp != NULL); 242 ASSERT(ifp->if_bytes == 0); 243 if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) { 244 ifp->if_flags &= ~XFS_IFEXTENTS; /* just in case */ 245 dp->i_d.di_aformat = XFS_DINODE_FMT_LOCAL; 246 ifp->if_flags |= XFS_IFINLINE; 247 } else { 248 ASSERT(ifp->if_flags & XFS_IFINLINE); 249 } 250 xfs_idata_realloc(dp, sizeof(*hdr), XFS_ATTR_FORK); 251 hdr = (xfs_attr_sf_hdr_t *)ifp->if_u1.if_data; 252 hdr->count = 0; 253 hdr->totsize = cpu_to_be16(sizeof(*hdr)); 254 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA); 255} 256 257/* 258 * Add a name/value pair to the shortform attribute list. 259 * Overflow from the inode has already been checked for. 260 */ 261void 262xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff) 263{ 264 xfs_attr_shortform_t *sf; 265 xfs_attr_sf_entry_t *sfe; 266 int i, offset, size; 267 xfs_mount_t *mp; 268 xfs_inode_t *dp; 269 xfs_ifork_t *ifp; 270 271 dp = args->dp; 272 mp = dp->i_mount; 273 dp->i_d.di_forkoff = forkoff; 274 dp->i_df.if_ext_max = 275 XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t); 276 dp->i_afp->if_ext_max = 277 XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t); 278 279 ifp = dp->i_afp; 280 ASSERT(ifp->if_flags & XFS_IFINLINE); 281 sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; 282 sfe = &sf->list[0]; 283 for (i = 0; i < sf->hdr.count; sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) { 284#ifdef DEBUG 285 if (sfe->namelen != args->namelen) 286 continue; 287 if (memcmp(args->name, sfe->nameval, args->namelen) != 0) 288 continue; 289 if (!xfs_attr_namesp_match(args->flags, sfe->flags)) 290 continue; 291 ASSERT(0); 292#endif 293 } 294 295 offset = (char *)sfe - (char *)sf; 296 size = XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen); 297 xfs_idata_realloc(dp, size, XFS_ATTR_FORK); 298 sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; 299 sfe = (xfs_attr_sf_entry_t *)((char *)sf + offset); 300 301 sfe->namelen = args->namelen; 302 sfe->valuelen = args->valuelen; 303 sfe->flags = XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags); 304 memcpy(sfe->nameval, args->name, args->namelen); 305 memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen); 306 sf->hdr.count++; 307 be16_add_cpu(&sf->hdr.totsize, size); 308 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA); 309 310 xfs_sbversion_add_attr2(mp, args->trans); 311} 312 313/* 314 * After the last attribute is removed revert to original inode format, 315 * making all literal area available to the data fork once more. 316 */ 317STATIC void 318xfs_attr_fork_reset( 319 struct xfs_inode *ip, 320 struct xfs_trans *tp) 321{ 322 xfs_idestroy_fork(ip, XFS_ATTR_FORK); 323 ip->i_d.di_forkoff = 0; 324 ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; 325 326 ASSERT(ip->i_d.di_anextents == 0); 327 ASSERT(ip->i_afp == NULL); 328 329 ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t); 330 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 331} 332 333/* 334 * Remove an attribute from the shortform attribute list structure. 335 */ 336int 337xfs_attr_shortform_remove(xfs_da_args_t *args) 338{ 339 xfs_attr_shortform_t *sf; 340 xfs_attr_sf_entry_t *sfe; 341 int base, size=0, end, totsize, i; 342 xfs_mount_t *mp; 343 xfs_inode_t *dp; 344 345 dp = args->dp; 346 mp = dp->i_mount; 347 base = sizeof(xfs_attr_sf_hdr_t); 348 sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data; 349 sfe = &sf->list[0]; 350 end = sf->hdr.count; 351 for (i = 0; i < end; sfe = XFS_ATTR_SF_NEXTENTRY(sfe), 352 base += size, i++) { 353 size = XFS_ATTR_SF_ENTSIZE(sfe); 354 if (sfe->namelen != args->namelen) 355 continue; 356 if (memcmp(sfe->nameval, args->name, args->namelen) != 0) 357 continue; 358 if (!xfs_attr_namesp_match(args->flags, sfe->flags)) 359 continue; 360 break; 361 } 362 if (i == end) 363 return(XFS_ERROR(ENOATTR)); 364 365 /* 366 * Fix up the attribute fork data, covering the hole 367 */ 368 end = base + size; 369 totsize = be16_to_cpu(sf->hdr.totsize); 370 if (end != totsize) 371 memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end); 372 sf->hdr.count--; 373 be16_add_cpu(&sf->hdr.totsize, -size); 374 375 /* 376 * Fix up the start offset of the attribute fork 377 */ 378 totsize -= size; 379 if (totsize == sizeof(xfs_attr_sf_hdr_t) && 380 (mp->m_flags & XFS_MOUNT_ATTR2) && 381 (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && 382 !(args->op_flags & XFS_DA_OP_ADDNAME)) { 383 xfs_attr_fork_reset(dp, args->trans); 384 } else { 385 xfs_idata_realloc(dp, -size, XFS_ATTR_FORK); 386 dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize); 387 ASSERT(dp->i_d.di_forkoff); 388 ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || 389 (args->op_flags & XFS_DA_OP_ADDNAME) || 390 !(mp->m_flags & XFS_MOUNT_ATTR2) || 391 dp->i_d.di_format == XFS_DINODE_FMT_BTREE); 392 dp->i_afp->if_ext_max = 393 XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t); 394 dp->i_df.if_ext_max = 395 XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t); 396 xfs_trans_log_inode(args->trans, dp, 397 XFS_ILOG_CORE | XFS_ILOG_ADATA); 398 } 399 400 xfs_sbversion_add_attr2(mp, args->trans); 401 402 return(0); 403} 404 405/* 406 * Look up a name in a shortform attribute list structure. 407 */ 408/*ARGSUSED*/ 409int 410xfs_attr_shortform_lookup(xfs_da_args_t *args) 411{ 412 xfs_attr_shortform_t *sf; 413 xfs_attr_sf_entry_t *sfe; 414 int i; 415 xfs_ifork_t *ifp; 416 417 ifp = args->dp->i_afp; 418 ASSERT(ifp->if_flags & XFS_IFINLINE); 419 sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; 420 sfe = &sf->list[0]; 421 for (i = 0; i < sf->hdr.count; 422 sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) { 423 if (sfe->namelen != args->namelen) 424 continue; 425 if (memcmp(args->name, sfe->nameval, args->namelen) != 0) 426 continue; 427 if (!xfs_attr_namesp_match(args->flags, sfe->flags)) 428 continue; 429 return(XFS_ERROR(EEXIST)); 430 } 431 return(XFS_ERROR(ENOATTR)); 432} 433 434/* 435 * Look up a name in a shortform attribute list structure. 436 */ 437/*ARGSUSED*/ 438int 439xfs_attr_shortform_getvalue(xfs_da_args_t *args) 440{ 441 xfs_attr_shortform_t *sf; 442 xfs_attr_sf_entry_t *sfe; 443 int i; 444 445 ASSERT(args->dp->i_d.di_aformat == XFS_IFINLINE); 446 sf = (xfs_attr_shortform_t *)args->dp->i_afp->if_u1.if_data; 447 sfe = &sf->list[0]; 448 for (i = 0; i < sf->hdr.count; 449 sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) { 450 if (sfe->namelen != args->namelen) 451 continue; 452 if (memcmp(args->name, sfe->nameval, args->namelen) != 0) 453 continue; 454 if (!xfs_attr_namesp_match(args->flags, sfe->flags)) 455 continue; 456 if (args->flags & ATTR_KERNOVAL) { 457 args->valuelen = sfe->valuelen; 458 return(XFS_ERROR(EEXIST)); 459 } 460 if (args->valuelen < sfe->valuelen) { 461 args->valuelen = sfe->valuelen; 462 return(XFS_ERROR(ERANGE)); 463 } 464 args->valuelen = sfe->valuelen; 465 memcpy(args->value, &sfe->nameval[args->namelen], 466 args->valuelen); 467 return(XFS_ERROR(EEXIST)); 468 } 469 return(XFS_ERROR(ENOATTR)); 470} 471 472/* 473 * Convert from using the shortform to the leaf. 474 */ 475int 476xfs_attr_shortform_to_leaf(xfs_da_args_t *args) 477{ 478 xfs_inode_t *dp; 479 xfs_attr_shortform_t *sf; 480 xfs_attr_sf_entry_t *sfe; 481 xfs_da_args_t nargs; 482 char *tmpbuffer; 483 int error, i, size; 484 xfs_dablk_t blkno; 485 xfs_dabuf_t *bp; 486 xfs_ifork_t *ifp; 487 488 dp = args->dp; 489 ifp = dp->i_afp; 490 sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; 491 size = be16_to_cpu(sf->hdr.totsize); 492 tmpbuffer = kmem_alloc(size, KM_SLEEP); 493 ASSERT(tmpbuffer != NULL); 494 memcpy(tmpbuffer, ifp->if_u1.if_data, size); 495 sf = (xfs_attr_shortform_t *)tmpbuffer; 496 497 xfs_idata_realloc(dp, -size, XFS_ATTR_FORK); 498 bp = NULL; 499 error = xfs_da_grow_inode(args, &blkno); 500 if (error) { 501 /* 502 * If we hit an IO error middle of the transaction inside 503 * grow_inode(), we may have inconsistent data. Bail out. 504 */ 505 if (error == EIO) 506 goto out; 507 xfs_idata_realloc(dp, size, XFS_ATTR_FORK); /* try to put */ 508 memcpy(ifp->if_u1.if_data, tmpbuffer, size); /* it back */ 509 goto out; 510 } 511 512 ASSERT(blkno == 0); 513 error = xfs_attr_leaf_create(args, blkno, &bp); 514 if (error) { 515 error = xfs_da_shrink_inode(args, 0, bp); 516 bp = NULL; 517 if (error) 518 goto out; 519 xfs_idata_realloc(dp, size, XFS_ATTR_FORK); /* try to put */ 520 memcpy(ifp->if_u1.if_data, tmpbuffer, size); /* it back */ 521 goto out; 522 } 523 524 memset((char *)&nargs, 0, sizeof(nargs)); 525 nargs.dp = dp; 526 nargs.firstblock = args->firstblock; 527 nargs.flist = args->flist; 528 nargs.total = args->total; 529 nargs.whichfork = XFS_ATTR_FORK; 530 nargs.trans = args->trans; 531 nargs.op_flags = XFS_DA_OP_OKNOENT; 532 533 sfe = &sf->list[0]; 534 for (i = 0; i < sf->hdr.count; i++) { 535 nargs.name = sfe->nameval; 536 nargs.namelen = sfe->namelen; 537 nargs.value = &sfe->nameval[nargs.namelen]; 538 nargs.valuelen = sfe->valuelen; 539 nargs.hashval = xfs_da_hashname(sfe->nameval, 540 sfe->namelen); 541 nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags); 542 error = xfs_attr_leaf_lookup_int(bp, &nargs); /* set a->index */ 543 ASSERT(error == ENOATTR); 544 error = xfs_attr_leaf_add(bp, &nargs); 545 ASSERT(error != ENOSPC); 546 if (error) 547 goto out; 548 sfe = XFS_ATTR_SF_NEXTENTRY(sfe); 549 } 550 error = 0; 551 552out: 553 if(bp) 554 xfs_da_buf_done(bp); 555 kmem_free(tmpbuffer); 556 return(error); 557} 558 559STATIC int 560xfs_attr_shortform_compare(const void *a, const void *b) 561{ 562 xfs_attr_sf_sort_t *sa, *sb; 563 564 sa = (xfs_attr_sf_sort_t *)a; 565 sb = (xfs_attr_sf_sort_t *)b; 566 if (sa->hash < sb->hash) { 567 return(-1); 568 } else if (sa->hash > sb->hash) { 569 return(1); 570 } else { 571 return(sa->entno - sb->entno); 572 } 573} 574 575 576#define XFS_ISRESET_CURSOR(cursor) \ 577 (!((cursor)->initted) && !((cursor)->hashval) && \ 578 !((cursor)->blkno) && !((cursor)->offset)) 579/* 580 * Copy out entries of shortform attribute lists for attr_list(). 581 * Shortform attribute lists are not stored in hashval sorted order. 582 * If the output buffer is not large enough to hold them all, then we 583 * we have to calculate each entries' hashvalue and sort them before 584 * we can begin returning them to the user. 585 */ 586/*ARGSUSED*/ 587int 588xfs_attr_shortform_list(xfs_attr_list_context_t *context) 589{ 590 attrlist_cursor_kern_t *cursor; 591 xfs_attr_sf_sort_t *sbuf, *sbp; 592 xfs_attr_shortform_t *sf; 593 xfs_attr_sf_entry_t *sfe; 594 xfs_inode_t *dp; 595 int sbsize, nsbuf, count, i; 596 int error; 597 598 ASSERT(context != NULL); 599 dp = context->dp; 600 ASSERT(dp != NULL); 601 ASSERT(dp->i_afp != NULL); 602 sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data; 603 ASSERT(sf != NULL); 604 if (!sf->hdr.count) 605 return(0); 606 cursor = context->cursor; 607 ASSERT(cursor != NULL); 608 609 trace_xfs_attr_list_sf(context); 610 611 /* 612 * If the buffer is large enough and the cursor is at the start, 613 * do not bother with sorting since we will return everything in 614 * one buffer and another call using the cursor won't need to be 615 * made. 616 * Note the generous fudge factor of 16 overhead bytes per entry. 617 * If bufsize is zero then put_listent must be a search function 618 * and can just scan through what we have. 619 */ 620 if (context->bufsize == 0 || 621 (XFS_ISRESET_CURSOR(cursor) && 622 (dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) { 623 for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { 624 error = context->put_listent(context, 625 sfe->flags, 626 sfe->nameval, 627 (int)sfe->namelen, 628 (int)sfe->valuelen, 629 &sfe->nameval[sfe->namelen]); 630 631 /* 632 * Either search callback finished early or 633 * didn't fit it all in the buffer after all. 634 */ 635 if (context->seen_enough) 636 break; 637 638 if (error) 639 return error; 640 sfe = XFS_ATTR_SF_NEXTENTRY(sfe); 641 } 642 trace_xfs_attr_list_sf_all(context); 643 return(0); 644 } 645 646 /* do no more for a search callback */ 647 if (context->bufsize == 0) 648 return 0; 649 650 /* 651 * It didn't all fit, so we have to sort everything on hashval. 652 */ 653 sbsize = sf->hdr.count * sizeof(*sbuf); 654 sbp = sbuf = kmem_alloc(sbsize, KM_SLEEP | KM_NOFS); 655 656 /* 657 * Scan the attribute list for the rest of the entries, storing 658 * the relevant info from only those that match into a buffer. 659 */ 660 nsbuf = 0; 661 for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { 662 if (unlikely( 663 ((char *)sfe < (char *)sf) || 664 ((char *)sfe >= ((char *)sf + dp->i_afp->if_bytes)))) { 665 XFS_CORRUPTION_ERROR("xfs_attr_shortform_list", 666 XFS_ERRLEVEL_LOW, 667 context->dp->i_mount, sfe); 668 kmem_free(sbuf); 669 return XFS_ERROR(EFSCORRUPTED); 670 } 671 672 sbp->entno = i; 673 sbp->hash = xfs_da_hashname(sfe->nameval, sfe->namelen); 674 sbp->name = sfe->nameval; 675 sbp->namelen = sfe->namelen; 676 /* These are bytes, and both on-disk, don't endian-flip */ 677 sbp->valuelen = sfe->valuelen; 678 sbp->flags = sfe->flags; 679 sfe = XFS_ATTR_SF_NEXTENTRY(sfe); 680 sbp++; 681 nsbuf++; 682 } 683 684 /* 685 * Sort the entries on hash then entno. 686 */ 687 xfs_sort(sbuf, nsbuf, sizeof(*sbuf), xfs_attr_shortform_compare); 688 689 /* 690 * Re-find our place IN THE SORTED LIST. 691 */ 692 count = 0; 693 cursor->initted = 1; 694 cursor->blkno = 0; 695 for (sbp = sbuf, i = 0; i < nsbuf; i++, sbp++) { 696 if (sbp->hash == cursor->hashval) { 697 if (cursor->offset == count) { 698 break; 699 } 700 count++; 701 } else if (sbp->hash > cursor->hashval) { 702 break; 703 } 704 } 705 if (i == nsbuf) { 706 kmem_free(sbuf); 707 return(0); 708 } 709 710 /* 711 * Loop putting entries into the user buffer. 712 */ 713 for ( ; i < nsbuf; i++, sbp++) { 714 if (cursor->hashval != sbp->hash) { 715 cursor->hashval = sbp->hash; 716 cursor->offset = 0; 717 } 718 error = context->put_listent(context, 719 sbp->flags, 720 sbp->name, 721 sbp->namelen, 722 sbp->valuelen, 723 &sbp->name[sbp->namelen]); 724 if (error) 725 return error; 726 if (context->seen_enough) 727 break; 728 cursor->offset++; 729 } 730 731 kmem_free(sbuf); 732 return(0); 733} 734 735/* 736 * Check a leaf attribute block to see if all the entries would fit into 737 * a shortform attribute list. 738 */ 739int 740xfs_attr_shortform_allfit(xfs_dabuf_t *bp, xfs_inode_t *dp) 741{ 742 xfs_attr_leafblock_t *leaf; 743 xfs_attr_leaf_entry_t *entry; 744 xfs_attr_leaf_name_local_t *name_loc; 745 int bytes, i; 746 747 leaf = bp->data; 748 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 749 750 entry = &leaf->entries[0]; 751 bytes = sizeof(struct xfs_attr_sf_hdr); 752 for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { 753 if (entry->flags & XFS_ATTR_INCOMPLETE) 754 continue; /* don't copy partial entries */ 755 if (!(entry->flags & XFS_ATTR_LOCAL)) 756 return(0); 757 name_loc = xfs_attr_leaf_name_local(leaf, i); 758 if (name_loc->namelen >= XFS_ATTR_SF_ENTSIZE_MAX) 759 return(0); 760 if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX) 761 return(0); 762 bytes += sizeof(struct xfs_attr_sf_entry)-1 763 + name_loc->namelen 764 + be16_to_cpu(name_loc->valuelen); 765 } 766 if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) && 767 (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && 768 (bytes == sizeof(struct xfs_attr_sf_hdr))) 769 return(-1); 770 return(xfs_attr_shortform_bytesfit(dp, bytes)); 771} 772 773/* 774 * Convert a leaf attribute list to shortform attribute list 775 */ 776int 777xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff) 778{ 779 xfs_attr_leafblock_t *leaf; 780 xfs_attr_leaf_entry_t *entry; 781 xfs_attr_leaf_name_local_t *name_loc; 782 xfs_da_args_t nargs; 783 xfs_inode_t *dp; 784 char *tmpbuffer; 785 int error, i; 786 787 dp = args->dp; 788 tmpbuffer = kmem_alloc(XFS_LBSIZE(dp->i_mount), KM_SLEEP); 789 ASSERT(tmpbuffer != NULL); 790 791 ASSERT(bp != NULL); 792 memcpy(tmpbuffer, bp->data, XFS_LBSIZE(dp->i_mount)); 793 leaf = (xfs_attr_leafblock_t *)tmpbuffer; 794 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 795 memset(bp->data, 0, XFS_LBSIZE(dp->i_mount)); 796 797 /* 798 * Clean out the prior contents of the attribute list. 799 */ 800 error = xfs_da_shrink_inode(args, 0, bp); 801 if (error) 802 goto out; 803 804 if (forkoff == -1) { 805 ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2); 806 ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE); 807 xfs_attr_fork_reset(dp, args->trans); 808 goto out; 809 } 810 811 xfs_attr_shortform_create(args); 812 813 /* 814 * Copy the attributes 815 */ 816 memset((char *)&nargs, 0, sizeof(nargs)); 817 nargs.dp = dp; 818 nargs.firstblock = args->firstblock; 819 nargs.flist = args->flist; 820 nargs.total = args->total; 821 nargs.whichfork = XFS_ATTR_FORK; 822 nargs.trans = args->trans; 823 nargs.op_flags = XFS_DA_OP_OKNOENT; 824 entry = &leaf->entries[0]; 825 for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { 826 if (entry->flags & XFS_ATTR_INCOMPLETE) 827 continue; /* don't copy partial entries */ 828 if (!entry->nameidx) 829 continue; 830 ASSERT(entry->flags & XFS_ATTR_LOCAL); 831 name_loc = xfs_attr_leaf_name_local(leaf, i); 832 nargs.name = name_loc->nameval; 833 nargs.namelen = name_loc->namelen; 834 nargs.value = &name_loc->nameval[nargs.namelen]; 835 nargs.valuelen = be16_to_cpu(name_loc->valuelen); 836 nargs.hashval = be32_to_cpu(entry->hashval); 837 nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(entry->flags); 838 xfs_attr_shortform_add(&nargs, forkoff); 839 } 840 error = 0; 841 842out: 843 kmem_free(tmpbuffer); 844 return(error); 845} 846 847/* 848 * Convert from using a single leaf to a root node and a leaf. 849 */ 850int 851xfs_attr_leaf_to_node(xfs_da_args_t *args) 852{ 853 xfs_attr_leafblock_t *leaf; 854 xfs_da_intnode_t *node; 855 xfs_inode_t *dp; 856 xfs_dabuf_t *bp1, *bp2; 857 xfs_dablk_t blkno; 858 int error; 859 860 dp = args->dp; 861 bp1 = bp2 = NULL; 862 error = xfs_da_grow_inode(args, &blkno); 863 if (error) 864 goto out; 865 error = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp1, 866 XFS_ATTR_FORK); 867 if (error) 868 goto out; 869 ASSERT(bp1 != NULL); 870 bp2 = NULL; 871 error = xfs_da_get_buf(args->trans, args->dp, blkno, -1, &bp2, 872 XFS_ATTR_FORK); 873 if (error) 874 goto out; 875 ASSERT(bp2 != NULL); 876 memcpy(bp2->data, bp1->data, XFS_LBSIZE(dp->i_mount)); 877 xfs_da_buf_done(bp1); 878 bp1 = NULL; 879 xfs_da_log_buf(args->trans, bp2, 0, XFS_LBSIZE(dp->i_mount) - 1); 880 881 /* 882 * Set up the new root node. 883 */ 884 error = xfs_da_node_create(args, 0, 1, &bp1, XFS_ATTR_FORK); 885 if (error) 886 goto out; 887 node = bp1->data; 888 leaf = bp2->data; 889 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 890 /* both on-disk, don't endian-flip twice */ 891 node->btree[0].hashval = 892 leaf->entries[be16_to_cpu(leaf->hdr.count)-1 ].hashval; 893 node->btree[0].before = cpu_to_be32(blkno); 894 node->hdr.count = cpu_to_be16(1); 895 xfs_da_log_buf(args->trans, bp1, 0, XFS_LBSIZE(dp->i_mount) - 1); 896 error = 0; 897out: 898 if (bp1) 899 xfs_da_buf_done(bp1); 900 if (bp2) 901 xfs_da_buf_done(bp2); 902 return(error); 903} 904 905 906/*======================================================================== 907 * Routines used for growing the Btree. 908 *========================================================================*/ 909 910/* 911 * Create the initial contents of a leaf attribute list 912 * or a leaf in a node attribute list. 913 */ 914STATIC int 915xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp) 916{ 917 xfs_attr_leafblock_t *leaf; 918 xfs_attr_leaf_hdr_t *hdr; 919 xfs_inode_t *dp; 920 xfs_dabuf_t *bp; 921 int error; 922 923 dp = args->dp; 924 ASSERT(dp != NULL); 925 error = xfs_da_get_buf(args->trans, args->dp, blkno, -1, &bp, 926 XFS_ATTR_FORK); 927 if (error) 928 return(error); 929 ASSERT(bp != NULL); 930 leaf = bp->data; 931 memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount)); 932 hdr = &leaf->hdr; 933 hdr->info.magic = cpu_to_be16(XFS_ATTR_LEAF_MAGIC); 934 hdr->firstused = cpu_to_be16(XFS_LBSIZE(dp->i_mount)); 935 if (!hdr->firstused) { 936 hdr->firstused = cpu_to_be16( 937 XFS_LBSIZE(dp->i_mount) - XFS_ATTR_LEAF_NAME_ALIGN); 938 } 939 940 hdr->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t)); 941 hdr->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr->firstused) - 942 sizeof(xfs_attr_leaf_hdr_t)); 943 944 xfs_da_log_buf(args->trans, bp, 0, XFS_LBSIZE(dp->i_mount) - 1); 945 946 *bpp = bp; 947 return(0); 948} 949 950/* 951 * Split the leaf node, rebalance, then add the new entry. 952 */ 953int 954xfs_attr_leaf_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, 955 xfs_da_state_blk_t *newblk) 956{ 957 xfs_dablk_t blkno; 958 int error; 959 960 /* 961 * Allocate space for a new leaf node. 962 */ 963 ASSERT(oldblk->magic == XFS_ATTR_LEAF_MAGIC); 964 error = xfs_da_grow_inode(state->args, &blkno); 965 if (error) 966 return(error); 967 error = xfs_attr_leaf_create(state->args, blkno, &newblk->bp); 968 if (error) 969 return(error); 970 newblk->blkno = blkno; 971 newblk->magic = XFS_ATTR_LEAF_MAGIC; 972 973 /* 974 * Rebalance the entries across the two leaves. 975 * NOTE: rebalance() currently depends on the 2nd block being empty. 976 */ 977 xfs_attr_leaf_rebalance(state, oldblk, newblk); 978 error = xfs_da_blk_link(state, oldblk, newblk); 979 if (error) 980 return(error); 981 982 /* 983 * Save info on "old" attribute for "atomic rename" ops, leaf_add() 984 * modifies the index/blkno/rmtblk/rmtblkcnt fields to show the 985 * "new" attrs info. Will need the "old" info to remove it later. 986 * 987 * Insert the "new" entry in the correct block. 988 */ 989 if (state->inleaf) 990 error = xfs_attr_leaf_add(oldblk->bp, state->args); 991 else 992 error = xfs_attr_leaf_add(newblk->bp, state->args); 993 994 /* 995 * Update last hashval in each block since we added the name. 996 */ 997 oldblk->hashval = xfs_attr_leaf_lasthash(oldblk->bp, NULL); 998 newblk->hashval = xfs_attr_leaf_lasthash(newblk->bp, NULL); 999 return(error); 1000} 1001 1002/* 1003 * Add a name to the leaf attribute list structure. 1004 */ 1005int 1006xfs_attr_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args) 1007{ 1008 xfs_attr_leafblock_t *leaf; 1009 xfs_attr_leaf_hdr_t *hdr; 1010 xfs_attr_leaf_map_t *map; 1011 int tablesize, entsize, sum, tmp, i; 1012 1013 leaf = bp->data; 1014 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1015 ASSERT((args->index >= 0) 1016 && (args->index <= be16_to_cpu(leaf->hdr.count))); 1017 hdr = &leaf->hdr; 1018 entsize = xfs_attr_leaf_newentsize(args->namelen, args->valuelen, 1019 args->trans->t_mountp->m_sb.sb_blocksize, NULL); 1020 1021 /* 1022 * Search through freemap for first-fit on new name length. 1023 * (may need to figure in size of entry struct too) 1024 */ 1025 tablesize = (be16_to_cpu(hdr->count) + 1) 1026 * sizeof(xfs_attr_leaf_entry_t) 1027 + sizeof(xfs_attr_leaf_hdr_t); 1028 map = &hdr->freemap[XFS_ATTR_LEAF_MAPSIZE-1]; 1029 for (sum = 0, i = XFS_ATTR_LEAF_MAPSIZE-1; i >= 0; map--, i--) { 1030 if (tablesize > be16_to_cpu(hdr->firstused)) { 1031 sum += be16_to_cpu(map->size); 1032 continue; 1033 } 1034 if (!map->size) 1035 continue; /* no space in this map */ 1036 tmp = entsize; 1037 if (be16_to_cpu(map->base) < be16_to_cpu(hdr->firstused)) 1038 tmp += sizeof(xfs_attr_leaf_entry_t); 1039 if (be16_to_cpu(map->size) >= tmp) { 1040 tmp = xfs_attr_leaf_add_work(bp, args, i); 1041 return(tmp); 1042 } 1043 sum += be16_to_cpu(map->size); 1044 } 1045 1046 /* 1047 * If there are no holes in the address space of the block, 1048 * and we don't have enough freespace, then compaction will do us 1049 * no good and we should just give up. 1050 */ 1051 if (!hdr->holes && (sum < entsize)) 1052 return(XFS_ERROR(ENOSPC)); 1053 1054 /* 1055 * Compact the entries to coalesce free space. 1056 * This may change the hdr->count via dropping INCOMPLETE entries. 1057 */ 1058 xfs_attr_leaf_compact(args->trans, bp); 1059 1060 /* 1061 * After compaction, the block is guaranteed to have only one 1062 * free region, in freemap[0]. If it is not big enough, give up. 1063 */ 1064 if (be16_to_cpu(hdr->freemap[0].size) 1065 < (entsize + sizeof(xfs_attr_leaf_entry_t))) 1066 return(XFS_ERROR(ENOSPC)); 1067 1068 return(xfs_attr_leaf_add_work(bp, args, 0)); 1069} 1070 1071/* 1072 * Add a name to a leaf attribute list structure. 1073 */ 1074STATIC int 1075xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) 1076{ 1077 xfs_attr_leafblock_t *leaf; 1078 xfs_attr_leaf_hdr_t *hdr; 1079 xfs_attr_leaf_entry_t *entry; 1080 xfs_attr_leaf_name_local_t *name_loc; 1081 xfs_attr_leaf_name_remote_t *name_rmt; 1082 xfs_attr_leaf_map_t *map; 1083 xfs_mount_t *mp; 1084 int tmp, i; 1085 1086 leaf = bp->data; 1087 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1088 hdr = &leaf->hdr; 1089 ASSERT((mapindex >= 0) && (mapindex < XFS_ATTR_LEAF_MAPSIZE)); 1090 ASSERT((args->index >= 0) && (args->index <= be16_to_cpu(hdr->count))); 1091 1092 /* 1093 * Force open some space in the entry array and fill it in. 1094 */ 1095 entry = &leaf->entries[args->index]; 1096 if (args->index < be16_to_cpu(hdr->count)) { 1097 tmp = be16_to_cpu(hdr->count) - args->index; 1098 tmp *= sizeof(xfs_attr_leaf_entry_t); 1099 memmove((char *)(entry+1), (char *)entry, tmp); 1100 xfs_da_log_buf(args->trans, bp, 1101 XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry))); 1102 } 1103 be16_add_cpu(&hdr->count, 1); 1104 1105 /* 1106 * Allocate space for the new string (at the end of the run). 1107 */ 1108 map = &hdr->freemap[mapindex]; 1109 mp = args->trans->t_mountp; 1110 ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp)); 1111 ASSERT((be16_to_cpu(map->base) & 0x3) == 0); 1112 ASSERT(be16_to_cpu(map->size) >= 1113 xfs_attr_leaf_newentsize(args->namelen, args->valuelen, 1114 mp->m_sb.sb_blocksize, NULL)); 1115 ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp)); 1116 ASSERT((be16_to_cpu(map->size) & 0x3) == 0); 1117 be16_add_cpu(&map->size, 1118 -xfs_attr_leaf_newentsize(args->namelen, args->valuelen, 1119 mp->m_sb.sb_blocksize, &tmp)); 1120 entry->nameidx = cpu_to_be16(be16_to_cpu(map->base) + 1121 be16_to_cpu(map->size)); 1122 entry->hashval = cpu_to_be32(args->hashval); 1123 entry->flags = tmp ? XFS_ATTR_LOCAL : 0; 1124 entry->flags |= XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags); 1125 if (args->op_flags & XFS_DA_OP_RENAME) { 1126 entry->flags |= XFS_ATTR_INCOMPLETE; 1127 if ((args->blkno2 == args->blkno) && 1128 (args->index2 <= args->index)) { 1129 args->index2++; 1130 } 1131 } 1132 xfs_da_log_buf(args->trans, bp, 1133 XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); 1134 ASSERT((args->index == 0) || 1135 (be32_to_cpu(entry->hashval) >= be32_to_cpu((entry-1)->hashval))); 1136 ASSERT((args->index == be16_to_cpu(hdr->count)-1) || 1137 (be32_to_cpu(entry->hashval) <= be32_to_cpu((entry+1)->hashval))); 1138 1139 /* 1140 * Copy the attribute name and value into the new space. 1141 * 1142 * For "remote" attribute values, simply note that we need to 1143 * allocate space for the "remote" value. We can't actually 1144 * allocate the extents in this transaction, and we can't decide 1145 * which blocks they should be as we might allocate more blocks 1146 * as part of this transaction (a split operation for example). 1147 */ 1148 if (entry->flags & XFS_ATTR_LOCAL) { 1149 name_loc = xfs_attr_leaf_name_local(leaf, args->index); 1150 name_loc->namelen = args->namelen; 1151 name_loc->valuelen = cpu_to_be16(args->valuelen); 1152 memcpy((char *)name_loc->nameval, args->name, args->namelen); 1153 memcpy((char *)&name_loc->nameval[args->namelen], args->value, 1154 be16_to_cpu(name_loc->valuelen)); 1155 } else { 1156 name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); 1157 name_rmt->namelen = args->namelen; 1158 memcpy((char *)name_rmt->name, args->name, args->namelen); 1159 entry->flags |= XFS_ATTR_INCOMPLETE; 1160 /* just in case */ 1161 name_rmt->valuelen = 0; 1162 name_rmt->valueblk = 0; 1163 args->rmtblkno = 1; 1164 args->rmtblkcnt = XFS_B_TO_FSB(mp, args->valuelen); 1165 } 1166 xfs_da_log_buf(args->trans, bp, 1167 XFS_DA_LOGRANGE(leaf, xfs_attr_leaf_name(leaf, args->index), 1168 xfs_attr_leaf_entsize(leaf, args->index))); 1169 1170 /* 1171 * Update the control info for this leaf node 1172 */ 1173 if (be16_to_cpu(entry->nameidx) < be16_to_cpu(hdr->firstused)) { 1174 /* both on-disk, don't endian-flip twice */ 1175 hdr->firstused = entry->nameidx; 1176 } 1177 ASSERT(be16_to_cpu(hdr->firstused) >= 1178 ((be16_to_cpu(hdr->count) * sizeof(*entry)) + sizeof(*hdr))); 1179 tmp = (be16_to_cpu(hdr->count)-1) * sizeof(xfs_attr_leaf_entry_t) 1180 + sizeof(xfs_attr_leaf_hdr_t); 1181 map = &hdr->freemap[0]; 1182 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) { 1183 if (be16_to_cpu(map->base) == tmp) { 1184 be16_add_cpu(&map->base, sizeof(xfs_attr_leaf_entry_t)); 1185 be16_add_cpu(&map->size, 1186 -((int)sizeof(xfs_attr_leaf_entry_t))); 1187 } 1188 } 1189 be16_add_cpu(&hdr->usedbytes, xfs_attr_leaf_entsize(leaf, args->index)); 1190 xfs_da_log_buf(args->trans, bp, 1191 XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); 1192 return(0); 1193} 1194 1195/* 1196 * Garbage collect a leaf attribute list block by copying it to a new buffer. 1197 */ 1198STATIC void 1199xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *bp) 1200{ 1201 xfs_attr_leafblock_t *leaf_s, *leaf_d; 1202 xfs_attr_leaf_hdr_t *hdr_s, *hdr_d; 1203 xfs_mount_t *mp; 1204 char *tmpbuffer; 1205 1206 mp = trans->t_mountp; 1207 tmpbuffer = kmem_alloc(XFS_LBSIZE(mp), KM_SLEEP); 1208 ASSERT(tmpbuffer != NULL); 1209 memcpy(tmpbuffer, bp->data, XFS_LBSIZE(mp)); 1210 memset(bp->data, 0, XFS_LBSIZE(mp)); 1211 1212 /* 1213 * Copy basic information 1214 */ 1215 leaf_s = (xfs_attr_leafblock_t *)tmpbuffer; 1216 leaf_d = bp->data; 1217 hdr_s = &leaf_s->hdr; 1218 hdr_d = &leaf_d->hdr; 1219 hdr_d->info = hdr_s->info; /* struct copy */ 1220 hdr_d->firstused = cpu_to_be16(XFS_LBSIZE(mp)); 1221 /* handle truncation gracefully */ 1222 if (!hdr_d->firstused) { 1223 hdr_d->firstused = cpu_to_be16( 1224 XFS_LBSIZE(mp) - XFS_ATTR_LEAF_NAME_ALIGN); 1225 } 1226 hdr_d->usedbytes = 0; 1227 hdr_d->count = 0; 1228 hdr_d->holes = 0; 1229 hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t)); 1230 hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused) - 1231 sizeof(xfs_attr_leaf_hdr_t)); 1232 1233 /* 1234 * Copy all entry's in the same (sorted) order, 1235 * but allocate name/value pairs packed and in sequence. 1236 */ 1237 xfs_attr_leaf_moveents(leaf_s, 0, leaf_d, 0, 1238 be16_to_cpu(hdr_s->count), mp); 1239 xfs_da_log_buf(trans, bp, 0, XFS_LBSIZE(mp) - 1); 1240 1241 kmem_free(tmpbuffer); 1242} 1243 1244/* 1245 * Redistribute the attribute list entries between two leaf nodes, 1246 * taking into account the size of the new entry. 1247 * 1248 * NOTE: if new block is empty, then it will get the upper half of the 1249 * old block. At present, all (one) callers pass in an empty second block. 1250 * 1251 * This code adjusts the args->index/blkno and args->index2/blkno2 fields 1252 * to match what it is doing in splitting the attribute leaf block. Those 1253 * values are used in "atomic rename" operations on attributes. Note that 1254 * the "new" and "old" values can end up in different blocks. 1255 */ 1256STATIC void 1257xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, 1258 xfs_da_state_blk_t *blk2) 1259{ 1260 xfs_da_args_t *args; 1261 xfs_da_state_blk_t *tmp_blk; 1262 xfs_attr_leafblock_t *leaf1, *leaf2; 1263 xfs_attr_leaf_hdr_t *hdr1, *hdr2; 1264 int count, totallen, max, space, swap; 1265 1266 /* 1267 * Set up environment. 1268 */ 1269 ASSERT(blk1->magic == XFS_ATTR_LEAF_MAGIC); 1270 ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC); 1271 leaf1 = blk1->bp->data; 1272 leaf2 = blk2->bp->data; 1273 ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1274 ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1275 args = state->args; 1276 1277 /* 1278 * Check ordering of blocks, reverse if it makes things simpler. 1279 * 1280 * NOTE: Given that all (current) callers pass in an empty 1281 * second block, this code should never set "swap". 1282 */ 1283 swap = 0; 1284 if (xfs_attr_leaf_order(blk1->bp, blk2->bp)) { 1285 tmp_blk = blk1; 1286 blk1 = blk2; 1287 blk2 = tmp_blk; 1288 leaf1 = blk1->bp->data; 1289 leaf2 = blk2->bp->data; 1290 swap = 1; 1291 } 1292 hdr1 = &leaf1->hdr; 1293 hdr2 = &leaf2->hdr; 1294 1295 /* 1296 * Examine entries until we reduce the absolute difference in 1297 * byte usage between the two blocks to a minimum. Then get 1298 * the direction to copy and the number of elements to move. 1299 * 1300 * "inleaf" is true if the new entry should be inserted into blk1. 1301 * If "swap" is also true, then reverse the sense of "inleaf". 1302 */ 1303 state->inleaf = xfs_attr_leaf_figure_balance(state, blk1, blk2, 1304 &count, &totallen); 1305 if (swap) 1306 state->inleaf = !state->inleaf; 1307 1308 /* 1309 * Move any entries required from leaf to leaf: 1310 */ 1311 if (count < be16_to_cpu(hdr1->count)) { 1312 /* 1313 * Figure the total bytes to be added to the destination leaf. 1314 */ 1315 /* number entries being moved */ 1316 count = be16_to_cpu(hdr1->count) - count; 1317 space = be16_to_cpu(hdr1->usedbytes) - totallen; 1318 space += count * sizeof(xfs_attr_leaf_entry_t); 1319 1320 /* 1321 * leaf2 is the destination, compact it if it looks tight. 1322 */ 1323 max = be16_to_cpu(hdr2->firstused) 1324 - sizeof(xfs_attr_leaf_hdr_t); 1325 max -= be16_to_cpu(hdr2->count) * sizeof(xfs_attr_leaf_entry_t); 1326 if (space > max) { 1327 xfs_attr_leaf_compact(args->trans, blk2->bp); 1328 } 1329 1330 /* 1331 * Move high entries from leaf1 to low end of leaf2. 1332 */ 1333 xfs_attr_leaf_moveents(leaf1, be16_to_cpu(hdr1->count) - count, 1334 leaf2, 0, count, state->mp); 1335 1336 xfs_da_log_buf(args->trans, blk1->bp, 0, state->blocksize-1); 1337 xfs_da_log_buf(args->trans, blk2->bp, 0, state->blocksize-1); 1338 } else if (count > be16_to_cpu(hdr1->count)) { 1339 /* 1340 * I assert that since all callers pass in an empty 1341 * second buffer, this code should never execute. 1342 */ 1343 1344 /* 1345 * Figure the total bytes to be added to the destination leaf. 1346 */ 1347 /* number entries being moved */ 1348 count -= be16_to_cpu(hdr1->count); 1349 space = totallen - be16_to_cpu(hdr1->usedbytes); 1350 space += count * sizeof(xfs_attr_leaf_entry_t); 1351 1352 /* 1353 * leaf1 is the destination, compact it if it looks tight. 1354 */ 1355 max = be16_to_cpu(hdr1->firstused) 1356 - sizeof(xfs_attr_leaf_hdr_t); 1357 max -= be16_to_cpu(hdr1->count) * sizeof(xfs_attr_leaf_entry_t); 1358 if (space > max) { 1359 xfs_attr_leaf_compact(args->trans, blk1->bp); 1360 } 1361 1362 /* 1363 * Move low entries from leaf2 to high end of leaf1. 1364 */ 1365 xfs_attr_leaf_moveents(leaf2, 0, leaf1, 1366 be16_to_cpu(hdr1->count), count, state->mp); 1367 1368 xfs_da_log_buf(args->trans, blk1->bp, 0, state->blocksize-1); 1369 xfs_da_log_buf(args->trans, blk2->bp, 0, state->blocksize-1); 1370 } 1371 1372 /* 1373 * Copy out last hashval in each block for B-tree code. 1374 */ 1375 blk1->hashval = be32_to_cpu( 1376 leaf1->entries[be16_to_cpu(leaf1->hdr.count)-1].hashval); 1377 blk2->hashval = be32_to_cpu( 1378 leaf2->entries[be16_to_cpu(leaf2->hdr.count)-1].hashval); 1379 1380 /* 1381 * Adjust the expected index for insertion. 1382 * NOTE: this code depends on the (current) situation that the 1383 * second block was originally empty. 1384 * 1385 * If the insertion point moved to the 2nd block, we must adjust 1386 * the index. We must also track the entry just following the 1387 * new entry for use in an "atomic rename" operation, that entry 1388 * is always the "old" entry and the "new" entry is what we are 1389 * inserting. The index/blkno fields refer to the "old" entry, 1390 * while the index2/blkno2 fields refer to the "new" entry. 1391 */ 1392 if (blk1->index > be16_to_cpu(leaf1->hdr.count)) { 1393 ASSERT(state->inleaf == 0); 1394 blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count); 1395 args->index = args->index2 = blk2->index; 1396 args->blkno = args->blkno2 = blk2->blkno; 1397 } else if (blk1->index == be16_to_cpu(leaf1->hdr.count)) { 1398 if (state->inleaf) { 1399 args->index = blk1->index; 1400 args->blkno = blk1->blkno; 1401 args->index2 = 0; 1402 args->blkno2 = blk2->blkno; 1403 } else { 1404 blk2->index = blk1->index 1405 - be16_to_cpu(leaf1->hdr.count); 1406 args->index = args->index2 = blk2->index; 1407 args->blkno = args->blkno2 = blk2->blkno; 1408 } 1409 } else { 1410 ASSERT(state->inleaf == 1); 1411 args->index = args->index2 = blk1->index; 1412 args->blkno = args->blkno2 = blk1->blkno; 1413 } 1414} 1415 1416/* 1417 * Examine entries until we reduce the absolute difference in 1418 * byte usage between the two blocks to a minimum. 1419 * GROT: Is this really necessary? With other than a 512 byte blocksize, 1420 * GROT: there will always be enough room in either block for a new entry. 1421 * GROT: Do a double-split for this case? 1422 */ 1423STATIC int 1424xfs_attr_leaf_figure_balance(xfs_da_state_t *state, 1425 xfs_da_state_blk_t *blk1, 1426 xfs_da_state_blk_t *blk2, 1427 int *countarg, int *usedbytesarg) 1428{ 1429 xfs_attr_leafblock_t *leaf1, *leaf2; 1430 xfs_attr_leaf_hdr_t *hdr1, *hdr2; 1431 xfs_attr_leaf_entry_t *entry; 1432 int count, max, index, totallen, half; 1433 int lastdelta, foundit, tmp; 1434 1435 /* 1436 * Set up environment. 1437 */ 1438 leaf1 = blk1->bp->data; 1439 leaf2 = blk2->bp->data; 1440 hdr1 = &leaf1->hdr; 1441 hdr2 = &leaf2->hdr; 1442 foundit = 0; 1443 totallen = 0; 1444 1445 /* 1446 * Examine entries until we reduce the absolute difference in 1447 * byte usage between the two blocks to a minimum. 1448 */ 1449 max = be16_to_cpu(hdr1->count) + be16_to_cpu(hdr2->count); 1450 half = (max+1) * sizeof(*entry); 1451 half += be16_to_cpu(hdr1->usedbytes) + 1452 be16_to_cpu(hdr2->usedbytes) + 1453 xfs_attr_leaf_newentsize( 1454 state->args->namelen, 1455 state->args->valuelen, 1456 state->blocksize, NULL); 1457 half /= 2; 1458 lastdelta = state->blocksize; 1459 entry = &leaf1->entries[0]; 1460 for (count = index = 0; count < max; entry++, index++, count++) { 1461 1462#define XFS_ATTR_ABS(A) (((A) < 0) ? -(A) : (A)) 1463 /* 1464 * The new entry is in the first block, account for it. 1465 */ 1466 if (count == blk1->index) { 1467 tmp = totallen + sizeof(*entry) + 1468 xfs_attr_leaf_newentsize( 1469 state->args->namelen, 1470 state->args->valuelen, 1471 state->blocksize, NULL); 1472 if (XFS_ATTR_ABS(half - tmp) > lastdelta) 1473 break; 1474 lastdelta = XFS_ATTR_ABS(half - tmp); 1475 totallen = tmp; 1476 foundit = 1; 1477 } 1478 1479 /* 1480 * Wrap around into the second block if necessary. 1481 */ 1482 if (count == be16_to_cpu(hdr1->count)) { 1483 leaf1 = leaf2; 1484 entry = &leaf1->entries[0]; 1485 index = 0; 1486 } 1487 1488 /* 1489 * Figure out if next leaf entry would be too much. 1490 */ 1491 tmp = totallen + sizeof(*entry) + xfs_attr_leaf_entsize(leaf1, 1492 index); 1493 if (XFS_ATTR_ABS(half - tmp) > lastdelta) 1494 break; 1495 lastdelta = XFS_ATTR_ABS(half - tmp); 1496 totallen = tmp; 1497#undef XFS_ATTR_ABS 1498 } 1499 1500 /* 1501 * Calculate the number of usedbytes that will end up in lower block. 1502 * If new entry not in lower block, fix up the count. 1503 */ 1504 totallen -= count * sizeof(*entry); 1505 if (foundit) { 1506 totallen -= sizeof(*entry) + 1507 xfs_attr_leaf_newentsize( 1508 state->args->namelen, 1509 state->args->valuelen, 1510 state->blocksize, NULL); 1511 } 1512 1513 *countarg = count; 1514 *usedbytesarg = totallen; 1515 return(foundit); 1516} 1517 1518/*======================================================================== 1519 * Routines used for shrinking the Btree. 1520 *========================================================================*/ 1521 1522/* 1523 * Check a leaf block and its neighbors to see if the block should be 1524 * collapsed into one or the other neighbor. Always keep the block 1525 * with the smaller block number. 1526 * If the current block is over 50% full, don't try to join it, return 0. 1527 * If the block is empty, fill in the state structure and return 2. 1528 * If it can be collapsed, fill in the state structure and return 1. 1529 * If nothing can be done, return 0. 1530 * 1531 * GROT: allow for INCOMPLETE entries in calculation. 1532 */ 1533int 1534xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action) 1535{ 1536 xfs_attr_leafblock_t *leaf; 1537 xfs_da_state_blk_t *blk; 1538 xfs_da_blkinfo_t *info; 1539 int count, bytes, forward, error, retval, i; 1540 xfs_dablk_t blkno; 1541 xfs_dabuf_t *bp; 1542 1543 /* 1544 * Check for the degenerate case of the block being over 50% full. 1545 * If so, it's not worth even looking to see if we might be able 1546 * to coalesce with a sibling. 1547 */ 1548 blk = &state->path.blk[ state->path.active-1 ]; 1549 info = blk->bp->data; 1550 ASSERT(info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1551 leaf = (xfs_attr_leafblock_t *)info; 1552 count = be16_to_cpu(leaf->hdr.count); 1553 bytes = sizeof(xfs_attr_leaf_hdr_t) + 1554 count * sizeof(xfs_attr_leaf_entry_t) + 1555 be16_to_cpu(leaf->hdr.usedbytes); 1556 if (bytes > (state->blocksize >> 1)) { 1557 *action = 0; /* blk over 50%, don't try to join */ 1558 return(0); 1559 } 1560 1561 /* 1562 * Check for the degenerate case of the block being empty. 1563 * If the block is empty, we'll simply delete it, no need to 1564 * coalesce it with a sibling block. We choose (arbitrarily) 1565 * to merge with the forward block unless it is NULL. 1566 */ 1567 if (count == 0) { 1568 /* 1569 * Make altpath point to the block we want to keep and 1570 * path point to the block we want to drop (this one). 1571 */ 1572 forward = (info->forw != 0); 1573 memcpy(&state->altpath, &state->path, sizeof(state->path)); 1574 error = xfs_da_path_shift(state, &state->altpath, forward, 1575 0, &retval); 1576 if (error) 1577 return(error); 1578 if (retval) { 1579 *action = 0; 1580 } else { 1581 *action = 2; 1582 } 1583 return(0); 1584 } 1585 1586 /* 1587 * Examine each sibling block to see if we can coalesce with 1588 * at least 25% free space to spare. We need to figure out 1589 * whether to merge with the forward or the backward block. 1590 * We prefer coalescing with the lower numbered sibling so as 1591 * to shrink an attribute list over time. 1592 */ 1593 /* start with smaller blk num */ 1594 forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back)); 1595 for (i = 0; i < 2; forward = !forward, i++) { 1596 if (forward) 1597 blkno = be32_to_cpu(info->forw); 1598 else 1599 blkno = be32_to_cpu(info->back); 1600 if (blkno == 0) 1601 continue; 1602 error = xfs_da_read_buf(state->args->trans, state->args->dp, 1603 blkno, -1, &bp, XFS_ATTR_FORK); 1604 if (error) 1605 return(error); 1606 ASSERT(bp != NULL); 1607 1608 leaf = (xfs_attr_leafblock_t *)info; 1609 count = be16_to_cpu(leaf->hdr.count); 1610 bytes = state->blocksize - (state->blocksize>>2); 1611 bytes -= be16_to_cpu(leaf->hdr.usedbytes); 1612 leaf = bp->data; 1613 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1614 count += be16_to_cpu(leaf->hdr.count); 1615 bytes -= be16_to_cpu(leaf->hdr.usedbytes); 1616 bytes -= count * sizeof(xfs_attr_leaf_entry_t); 1617 bytes -= sizeof(xfs_attr_leaf_hdr_t); 1618 xfs_da_brelse(state->args->trans, bp); 1619 if (bytes >= 0) 1620 break; /* fits with at least 25% to spare */ 1621 } 1622 if (i >= 2) { 1623 *action = 0; 1624 return(0); 1625 } 1626 1627 /* 1628 * Make altpath point to the block we want to keep (the lower 1629 * numbered block) and path point to the block we want to drop. 1630 */ 1631 memcpy(&state->altpath, &state->path, sizeof(state->path)); 1632 if (blkno < blk->blkno) { 1633 error = xfs_da_path_shift(state, &state->altpath, forward, 1634 0, &retval); 1635 } else { 1636 error = xfs_da_path_shift(state, &state->path, forward, 1637 0, &retval); 1638 } 1639 if (error) 1640 return(error); 1641 if (retval) { 1642 *action = 0; 1643 } else { 1644 *action = 1; 1645 } 1646 return(0); 1647} 1648 1649/* 1650 * Remove a name from the leaf attribute list structure. 1651 * 1652 * Return 1 if leaf is less than 37% full, 0 if >= 37% full. 1653 * If two leaves are 37% full, when combined they will leave 25% free. 1654 */ 1655int 1656xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) 1657{ 1658 xfs_attr_leafblock_t *leaf; 1659 xfs_attr_leaf_hdr_t *hdr; 1660 xfs_attr_leaf_map_t *map; 1661 xfs_attr_leaf_entry_t *entry; 1662 int before, after, smallest, entsize; 1663 int tablesize, tmp, i; 1664 xfs_mount_t *mp; 1665 1666 leaf = bp->data; 1667 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1668 hdr = &leaf->hdr; 1669 mp = args->trans->t_mountp; 1670 ASSERT((be16_to_cpu(hdr->count) > 0) 1671 && (be16_to_cpu(hdr->count) < (XFS_LBSIZE(mp)/8))); 1672 ASSERT((args->index >= 0) 1673 && (args->index < be16_to_cpu(hdr->count))); 1674 ASSERT(be16_to_cpu(hdr->firstused) >= 1675 ((be16_to_cpu(hdr->count) * sizeof(*entry)) + sizeof(*hdr))); 1676 entry = &leaf->entries[args->index]; 1677 ASSERT(be16_to_cpu(entry->nameidx) >= be16_to_cpu(hdr->firstused)); 1678 ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp)); 1679 1680 /* 1681 * Scan through free region table: 1682 * check for adjacency of free'd entry with an existing one, 1683 * find smallest free region in case we need to replace it, 1684 * adjust any map that borders the entry table, 1685 */ 1686 tablesize = be16_to_cpu(hdr->count) * sizeof(xfs_attr_leaf_entry_t) 1687 + sizeof(xfs_attr_leaf_hdr_t); 1688 map = &hdr->freemap[0]; 1689 tmp = be16_to_cpu(map->size); 1690 before = after = -1; 1691 smallest = XFS_ATTR_LEAF_MAPSIZE - 1; 1692 entsize = xfs_attr_leaf_entsize(leaf, args->index); 1693 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) { 1694 ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp)); 1695 ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp)); 1696 if (be16_to_cpu(map->base) == tablesize) { 1697 be16_add_cpu(&map->base, 1698 -((int)sizeof(xfs_attr_leaf_entry_t))); 1699 be16_add_cpu(&map->size, sizeof(xfs_attr_leaf_entry_t)); 1700 } 1701 1702 if ((be16_to_cpu(map->base) + be16_to_cpu(map->size)) 1703 == be16_to_cpu(entry->nameidx)) { 1704 before = i; 1705 } else if (be16_to_cpu(map->base) 1706 == (be16_to_cpu(entry->nameidx) + entsize)) { 1707 after = i; 1708 } else if (be16_to_cpu(map->size) < tmp) { 1709 tmp = be16_to_cpu(map->size); 1710 smallest = i; 1711 } 1712 } 1713 1714 /* 1715 * Coalesce adjacent freemap regions, 1716 * or replace the smallest region. 1717 */ 1718 if ((before >= 0) || (after >= 0)) { 1719 if ((before >= 0) && (after >= 0)) { 1720 map = &hdr->freemap[before]; 1721 be16_add_cpu(&map->size, entsize); 1722 be16_add_cpu(&map->size, 1723 be16_to_cpu(hdr->freemap[after].size)); 1724 hdr->freemap[after].base = 0; 1725 hdr->freemap[after].size = 0; 1726 } else if (before >= 0) { 1727 map = &hdr->freemap[before]; 1728 be16_add_cpu(&map->size, entsize); 1729 } else { 1730 map = &hdr->freemap[after]; 1731 /* both on-disk, don't endian flip twice */ 1732 map->base = entry->nameidx; 1733 be16_add_cpu(&map->size, entsize); 1734 } 1735 } else { 1736 /* 1737 * Replace smallest region (if it is smaller than free'd entry) 1738 */ 1739 map = &hdr->freemap[smallest]; 1740 if (be16_to_cpu(map->size) < entsize) { 1741 map->base = cpu_to_be16(be16_to_cpu(entry->nameidx)); 1742 map->size = cpu_to_be16(entsize); 1743 } 1744 } 1745 1746 /* 1747 * Did we remove the first entry? 1748 */ 1749 if (be16_to_cpu(entry->nameidx) == be16_to_cpu(hdr->firstused)) 1750 smallest = 1; 1751 else 1752 smallest = 0; 1753 1754 /* 1755 * Compress the remaining entries and zero out the removed stuff. 1756 */ 1757 memset(xfs_attr_leaf_name(leaf, args->index), 0, entsize); 1758 be16_add_cpu(&hdr->usedbytes, -entsize); 1759 xfs_da_log_buf(args->trans, bp, 1760 XFS_DA_LOGRANGE(leaf, xfs_attr_leaf_name(leaf, args->index), 1761 entsize)); 1762 1763 tmp = (be16_to_cpu(hdr->count) - args->index) 1764 * sizeof(xfs_attr_leaf_entry_t); 1765 memmove((char *)entry, (char *)(entry+1), tmp); 1766 be16_add_cpu(&hdr->count, -1); 1767 xfs_da_log_buf(args->trans, bp, 1768 XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry))); 1769 entry = &leaf->entries[be16_to_cpu(hdr->count)]; 1770 memset((char *)entry, 0, sizeof(xfs_attr_leaf_entry_t)); 1771 1772 /* 1773 * If we removed the first entry, re-find the first used byte 1774 * in the name area. Note that if the entry was the "firstused", 1775 * then we don't have a "hole" in our block resulting from 1776 * removing the name. 1777 */ 1778 if (smallest) { 1779 tmp = XFS_LBSIZE(mp); 1780 entry = &leaf->entries[0]; 1781 for (i = be16_to_cpu(hdr->count)-1; i >= 0; entry++, i--) { 1782 ASSERT(be16_to_cpu(entry->nameidx) >= 1783 be16_to_cpu(hdr->firstused)); 1784 ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp)); 1785 1786 if (be16_to_cpu(entry->nameidx) < tmp) 1787 tmp = be16_to_cpu(entry->nameidx); 1788 } 1789 hdr->firstused = cpu_to_be16(tmp); 1790 if (!hdr->firstused) { 1791 hdr->firstused = cpu_to_be16( 1792 tmp - XFS_ATTR_LEAF_NAME_ALIGN); 1793 } 1794 } else { 1795 hdr->holes = 1; /* mark as needing compaction */ 1796 } 1797 xfs_da_log_buf(args->trans, bp, 1798 XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); 1799 1800 /* 1801 * Check if leaf is less than 50% full, caller may want to 1802 * "join" the leaf with a sibling if so. 1803 */ 1804 tmp = sizeof(xfs_attr_leaf_hdr_t); 1805 tmp += be16_to_cpu(leaf->hdr.count) * sizeof(xfs_attr_leaf_entry_t); 1806 tmp += be16_to_cpu(leaf->hdr.usedbytes); 1807 return(tmp < mp->m_attr_magicpct); /* leaf is < 37% full */ 1808} 1809 1810/* 1811 * Move all the attribute list entries from drop_leaf into save_leaf. 1812 */ 1813void 1814xfs_attr_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, 1815 xfs_da_state_blk_t *save_blk) 1816{ 1817 xfs_attr_leafblock_t *drop_leaf, *save_leaf, *tmp_leaf; 1818 xfs_attr_leaf_hdr_t *drop_hdr, *save_hdr, *tmp_hdr; 1819 xfs_mount_t *mp; 1820 char *tmpbuffer; 1821 1822 /* 1823 * Set up environment. 1824 */ 1825 mp = state->mp; 1826 ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC); 1827 ASSERT(save_blk->magic == XFS_ATTR_LEAF_MAGIC); 1828 drop_leaf = drop_blk->bp->data; 1829 save_leaf = save_blk->bp->data; 1830 ASSERT(drop_leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1831 ASSERT(save_leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1832 drop_hdr = &drop_leaf->hdr; 1833 save_hdr = &save_leaf->hdr; 1834 1835 /* 1836 * Save last hashval from dying block for later Btree fixup. 1837 */ 1838 drop_blk->hashval = be32_to_cpu( 1839 drop_leaf->entries[be16_to_cpu(drop_leaf->hdr.count)-1].hashval); 1840 1841 /* 1842 * Check if we need a temp buffer, or can we do it in place. 1843 * Note that we don't check "leaf" for holes because we will 1844 * always be dropping it, toosmall() decided that for us already. 1845 */ 1846 if (save_hdr->holes == 0) { 1847 /* 1848 * dest leaf has no holes, so we add there. May need 1849 * to make some room in the entry array. 1850 */ 1851 if (xfs_attr_leaf_order(save_blk->bp, drop_blk->bp)) { 1852 xfs_attr_leaf_moveents(drop_leaf, 0, save_leaf, 0, 1853 be16_to_cpu(drop_hdr->count), mp); 1854 } else { 1855 xfs_attr_leaf_moveents(drop_leaf, 0, save_leaf, 1856 be16_to_cpu(save_hdr->count), 1857 be16_to_cpu(drop_hdr->count), mp); 1858 } 1859 } else { 1860 /* 1861 * Destination has holes, so we make a temporary copy 1862 * of the leaf and add them both to that. 1863 */ 1864 tmpbuffer = kmem_alloc(state->blocksize, KM_SLEEP); 1865 ASSERT(tmpbuffer != NULL); 1866 memset(tmpbuffer, 0, state->blocksize); 1867 tmp_leaf = (xfs_attr_leafblock_t *)tmpbuffer; 1868 tmp_hdr = &tmp_leaf->hdr; 1869 tmp_hdr->info = save_hdr->info; /* struct copy */ 1870 tmp_hdr->count = 0; 1871 tmp_hdr->firstused = cpu_to_be16(state->blocksize); 1872 if (!tmp_hdr->firstused) { 1873 tmp_hdr->firstused = cpu_to_be16( 1874 state->blocksize - XFS_ATTR_LEAF_NAME_ALIGN); 1875 } 1876 tmp_hdr->usedbytes = 0; 1877 if (xfs_attr_leaf_order(save_blk->bp, drop_blk->bp)) { 1878 xfs_attr_leaf_moveents(drop_leaf, 0, tmp_leaf, 0, 1879 be16_to_cpu(drop_hdr->count), mp); 1880 xfs_attr_leaf_moveents(save_leaf, 0, tmp_leaf, 1881 be16_to_cpu(tmp_leaf->hdr.count), 1882 be16_to_cpu(save_hdr->count), mp); 1883 } else { 1884 xfs_attr_leaf_moveents(save_leaf, 0, tmp_leaf, 0, 1885 be16_to_cpu(save_hdr->count), mp); 1886 xfs_attr_leaf_moveents(drop_leaf, 0, tmp_leaf, 1887 be16_to_cpu(tmp_leaf->hdr.count), 1888 be16_to_cpu(drop_hdr->count), mp); 1889 } 1890 memcpy((char *)save_leaf, (char *)tmp_leaf, state->blocksize); 1891 kmem_free(tmpbuffer); 1892 } 1893 1894 xfs_da_log_buf(state->args->trans, save_blk->bp, 0, 1895 state->blocksize - 1); 1896 1897 /* 1898 * Copy out last hashval in each block for B-tree code. 1899 */ 1900 save_blk->hashval = be32_to_cpu( 1901 save_leaf->entries[be16_to_cpu(save_leaf->hdr.count)-1].hashval); 1902} 1903 1904/*======================================================================== 1905 * Routines used for finding things in the Btree. 1906 *========================================================================*/ 1907 1908/* 1909 * Look up a name in a leaf attribute list structure. 1910 * This is the internal routine, it uses the caller's buffer. 1911 * 1912 * Note that duplicate keys are allowed, but only check within the 1913 * current leaf node. The Btree code must check in adjacent leaf nodes. 1914 * 1915 * Return in args->index the index into the entry[] array of either 1916 * the found entry, or where the entry should have been (insert before 1917 * that entry). 1918 * 1919 * Don't change the args->value unless we find the attribute. 1920 */ 1921int 1922xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) 1923{ 1924 xfs_attr_leafblock_t *leaf; 1925 xfs_attr_leaf_entry_t *entry; 1926 xfs_attr_leaf_name_local_t *name_loc; 1927 xfs_attr_leaf_name_remote_t *name_rmt; 1928 int probe, span; 1929 xfs_dahash_t hashval; 1930 1931 leaf = bp->data; 1932 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1933 ASSERT(be16_to_cpu(leaf->hdr.count) 1934 < (XFS_LBSIZE(args->dp->i_mount)/8)); 1935 1936 /* 1937 * Binary search. (note: small blocks will skip this loop) 1938 */ 1939 hashval = args->hashval; 1940 probe = span = be16_to_cpu(leaf->hdr.count) / 2; 1941 for (entry = &leaf->entries[probe]; span > 4; 1942 entry = &leaf->entries[probe]) { 1943 span /= 2; 1944 if (be32_to_cpu(entry->hashval) < hashval) 1945 probe += span; 1946 else if (be32_to_cpu(entry->hashval) > hashval) 1947 probe -= span; 1948 else 1949 break; 1950 } 1951 ASSERT((probe >= 0) && 1952 (!leaf->hdr.count 1953 || (probe < be16_to_cpu(leaf->hdr.count)))); 1954 ASSERT((span <= 4) || (be32_to_cpu(entry->hashval) == hashval)); 1955 1956 /* 1957 * Since we may have duplicate hashval's, find the first matching 1958 * hashval in the leaf. 1959 */ 1960 while ((probe > 0) && (be32_to_cpu(entry->hashval) >= hashval)) { 1961 entry--; 1962 probe--; 1963 } 1964 while ((probe < be16_to_cpu(leaf->hdr.count)) && 1965 (be32_to_cpu(entry->hashval) < hashval)) { 1966 entry++; 1967 probe++; 1968 } 1969 if ((probe == be16_to_cpu(leaf->hdr.count)) || 1970 (be32_to_cpu(entry->hashval) != hashval)) { 1971 args->index = probe; 1972 return(XFS_ERROR(ENOATTR)); 1973 } 1974 1975 /* 1976 * Duplicate keys may be present, so search all of them for a match. 1977 */ 1978 for ( ; (probe < be16_to_cpu(leaf->hdr.count)) && 1979 (be32_to_cpu(entry->hashval) == hashval); 1980 entry++, probe++) { 1981/* 1982 * GROT: Add code to remove incomplete entries. 1983 */ 1984 /* 1985 * If we are looking for INCOMPLETE entries, show only those. 1986 * If we are looking for complete entries, show only those. 1987 */ 1988 if ((args->flags & XFS_ATTR_INCOMPLETE) != 1989 (entry->flags & XFS_ATTR_INCOMPLETE)) { 1990 continue; 1991 } 1992 if (entry->flags & XFS_ATTR_LOCAL) { 1993 name_loc = xfs_attr_leaf_name_local(leaf, probe); 1994 if (name_loc->namelen != args->namelen) 1995 continue; 1996 if (memcmp(args->name, (char *)name_loc->nameval, args->namelen) != 0) 1997 continue; 1998 if (!xfs_attr_namesp_match(args->flags, entry->flags)) 1999 continue; 2000 args->index = probe; 2001 return(XFS_ERROR(EEXIST)); 2002 } else { 2003 name_rmt = xfs_attr_leaf_name_remote(leaf, probe); 2004 if (name_rmt->namelen != args->namelen) 2005 continue; 2006 if (memcmp(args->name, (char *)name_rmt->name, 2007 args->namelen) != 0) 2008 continue; 2009 if (!xfs_attr_namesp_match(args->flags, entry->flags)) 2010 continue; 2011 args->index = probe; 2012 args->rmtblkno = be32_to_cpu(name_rmt->valueblk); 2013 args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, 2014 be32_to_cpu(name_rmt->valuelen)); 2015 return(XFS_ERROR(EEXIST)); 2016 } 2017 } 2018 args->index = probe; 2019 return(XFS_ERROR(ENOATTR)); 2020} 2021 2022/* 2023 * Get the value associated with an attribute name from a leaf attribute 2024 * list structure. 2025 */ 2026int 2027xfs_attr_leaf_getvalue(xfs_dabuf_t *bp, xfs_da_args_t *args) 2028{ 2029 int valuelen; 2030 xfs_attr_leafblock_t *leaf; 2031 xfs_attr_leaf_entry_t *entry; 2032 xfs_attr_leaf_name_local_t *name_loc; 2033 xfs_attr_leaf_name_remote_t *name_rmt; 2034 2035 leaf = bp->data; 2036 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 2037 ASSERT(be16_to_cpu(leaf->hdr.count) 2038 < (XFS_LBSIZE(args->dp->i_mount)/8)); 2039 ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); 2040 2041 entry = &leaf->entries[args->index]; 2042 if (entry->flags & XFS_ATTR_LOCAL) { 2043 name_loc = xfs_attr_leaf_name_local(leaf, args->index); 2044 ASSERT(name_loc->namelen == args->namelen); 2045 ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0); 2046 valuelen = be16_to_cpu(name_loc->valuelen); 2047 if (args->flags & ATTR_KERNOVAL) { 2048 args->valuelen = valuelen; 2049 return(0); 2050 } 2051 if (args->valuelen < valuelen) { 2052 args->valuelen = valuelen; 2053 return(XFS_ERROR(ERANGE)); 2054 } 2055 args->valuelen = valuelen; 2056 memcpy(args->value, &name_loc->nameval[args->namelen], valuelen); 2057 } else { 2058 name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); 2059 ASSERT(name_rmt->namelen == args->namelen); 2060 ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0); 2061 valuelen = be32_to_cpu(name_rmt->valuelen); 2062 args->rmtblkno = be32_to_cpu(name_rmt->valueblk); 2063 args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, valuelen); 2064 if (args->flags & ATTR_KERNOVAL) { 2065 args->valuelen = valuelen; 2066 return(0); 2067 } 2068 if (args->valuelen < valuelen) { 2069 args->valuelen = valuelen; 2070 return(XFS_ERROR(ERANGE)); 2071 } 2072 args->valuelen = valuelen; 2073 } 2074 return(0); 2075} 2076 2077/*======================================================================== 2078 * Utility routines. 2079 *========================================================================*/ 2080 2081/* 2082 * Move the indicated entries from one leaf to another. 2083 * NOTE: this routine modifies both source and destination leaves. 2084 */ 2085/*ARGSUSED*/ 2086STATIC void 2087xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s, 2088 xfs_attr_leafblock_t *leaf_d, int start_d, 2089 int count, xfs_mount_t *mp) 2090{ 2091 xfs_attr_leaf_hdr_t *hdr_s, *hdr_d; 2092 xfs_attr_leaf_entry_t *entry_s, *entry_d; 2093 int desti, tmp, i; 2094 2095 /* 2096 * Check for nothing to do. 2097 */ 2098 if (count == 0) 2099 return; 2100 2101 /* 2102 * Set up environment. 2103 */ 2104 ASSERT(leaf_s->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 2105 ASSERT(leaf_d->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 2106 hdr_s = &leaf_s->hdr; 2107 hdr_d = &leaf_d->hdr; 2108 ASSERT((be16_to_cpu(hdr_s->count) > 0) && 2109 (be16_to_cpu(hdr_s->count) < (XFS_LBSIZE(mp)/8))); 2110 ASSERT(be16_to_cpu(hdr_s->firstused) >= 2111 ((be16_to_cpu(hdr_s->count) 2112 * sizeof(*entry_s))+sizeof(*hdr_s))); 2113 ASSERT(be16_to_cpu(hdr_d->count) < (XFS_LBSIZE(mp)/8)); 2114 ASSERT(be16_to_cpu(hdr_d->firstused) >= 2115 ((be16_to_cpu(hdr_d->count) 2116 * sizeof(*entry_d))+sizeof(*hdr_d))); 2117 2118 ASSERT(start_s < be16_to_cpu(hdr_s->count)); 2119 ASSERT(start_d <= be16_to_cpu(hdr_d->count)); 2120 ASSERT(count <= be16_to_cpu(hdr_s->count)); 2121 2122 /* 2123 * Move the entries in the destination leaf up to make a hole? 2124 */ 2125 if (start_d < be16_to_cpu(hdr_d->count)) { 2126 tmp = be16_to_cpu(hdr_d->count) - start_d; 2127 tmp *= sizeof(xfs_attr_leaf_entry_t); 2128 entry_s = &leaf_d->entries[start_d]; 2129 entry_d = &leaf_d->entries[start_d + count]; 2130 memmove((char *)entry_d, (char *)entry_s, tmp); 2131 } 2132 2133 /* 2134 * Copy all entry's in the same (sorted) order, 2135 * but allocate attribute info packed and in sequence. 2136 */ 2137 entry_s = &leaf_s->entries[start_s]; 2138 entry_d = &leaf_d->entries[start_d]; 2139 desti = start_d; 2140 for (i = 0; i < count; entry_s++, entry_d++, desti++, i++) { 2141 ASSERT(be16_to_cpu(entry_s->nameidx) 2142 >= be16_to_cpu(hdr_s->firstused)); 2143 tmp = xfs_attr_leaf_entsize(leaf_s, start_s + i); 2144#ifdef GROT 2145 /* 2146 * Code to drop INCOMPLETE entries. Difficult to use as we 2147 * may also need to change the insertion index. Code turned 2148 * off for 6.2, should be revisited later. 2149 */ 2150 if (entry_s->flags & XFS_ATTR_INCOMPLETE) { /* skip partials? */ 2151 memset(xfs_attr_leaf_name(leaf_s, start_s + i), 0, tmp); 2152 be16_add_cpu(&hdr_s->usedbytes, -tmp); 2153 be16_add_cpu(&hdr_s->count, -1); 2154 entry_d--; /* to compensate for ++ in loop hdr */ 2155 desti--; 2156 if ((start_s + i) < offset) 2157 result++; /* insertion index adjustment */ 2158 } else { 2159#endif /* GROT */ 2160 be16_add_cpu(&hdr_d->firstused, -tmp); 2161 /* both on-disk, don't endian flip twice */ 2162 entry_d->hashval = entry_s->hashval; 2163 /* both on-disk, don't endian flip twice */ 2164 entry_d->nameidx = hdr_d->firstused; 2165 entry_d->flags = entry_s->flags; 2166 ASSERT(be16_to_cpu(entry_d->nameidx) + tmp 2167 <= XFS_LBSIZE(mp)); 2168 memmove(xfs_attr_leaf_name(leaf_d, desti), 2169 xfs_attr_leaf_name(leaf_s, start_s + i), tmp); 2170 ASSERT(be16_to_cpu(entry_s->nameidx) + tmp 2171 <= XFS_LBSIZE(mp)); 2172 memset(xfs_attr_leaf_name(leaf_s, start_s + i), 0, tmp); 2173 be16_add_cpu(&hdr_s->usedbytes, -tmp); 2174 be16_add_cpu(&hdr_d->usedbytes, tmp); 2175 be16_add_cpu(&hdr_s->count, -1); 2176 be16_add_cpu(&hdr_d->count, 1); 2177 tmp = be16_to_cpu(hdr_d->count) 2178 * sizeof(xfs_attr_leaf_entry_t) 2179 + sizeof(xfs_attr_leaf_hdr_t); 2180 ASSERT(be16_to_cpu(hdr_d->firstused) >= tmp); 2181#ifdef GROT 2182 } 2183#endif /* GROT */ 2184 } 2185 2186 /* 2187 * Zero out the entries we just copied. 2188 */ 2189 if (start_s == be16_to_cpu(hdr_s->count)) { 2190 tmp = count * sizeof(xfs_attr_leaf_entry_t); 2191 entry_s = &leaf_s->entries[start_s]; 2192 ASSERT(((char *)entry_s + tmp) <= 2193 ((char *)leaf_s + XFS_LBSIZE(mp))); 2194 memset((char *)entry_s, 0, tmp); 2195 } else { 2196 /* 2197 * Move the remaining entries down to fill the hole, 2198 * then zero the entries at the top. 2199 */ 2200 tmp = be16_to_cpu(hdr_s->count) - count; 2201 tmp *= sizeof(xfs_attr_leaf_entry_t); 2202 entry_s = &leaf_s->entries[start_s + count]; 2203 entry_d = &leaf_s->entries[start_s]; 2204 memmove((char *)entry_d, (char *)entry_s, tmp); 2205 2206 tmp = count * sizeof(xfs_attr_leaf_entry_t); 2207 entry_s = &leaf_s->entries[be16_to_cpu(hdr_s->count)]; 2208 ASSERT(((char *)entry_s + tmp) <= 2209 ((char *)leaf_s + XFS_LBSIZE(mp))); 2210 memset((char *)entry_s, 0, tmp); 2211 } 2212 2213 /* 2214 * Fill in the freemap information 2215 */ 2216 hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t)); 2217 be16_add_cpu(&hdr_d->freemap[0].base, be16_to_cpu(hdr_d->count) * 2218 sizeof(xfs_attr_leaf_entry_t)); 2219 hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused) 2220 - be16_to_cpu(hdr_d->freemap[0].base)); 2221 hdr_d->freemap[1].base = 0; 2222 hdr_d->freemap[2].base = 0; 2223 hdr_d->freemap[1].size = 0; 2224 hdr_d->freemap[2].size = 0; 2225 hdr_s->holes = 1; /* leaf may not be compact */ 2226} 2227 2228/* 2229 * Compare two leaf blocks "order". 2230 * Return 0 unless leaf2 should go before leaf1. 2231 */ 2232int 2233xfs_attr_leaf_order(xfs_dabuf_t *leaf1_bp, xfs_dabuf_t *leaf2_bp) 2234{ 2235 xfs_attr_leafblock_t *leaf1, *leaf2; 2236 2237 leaf1 = leaf1_bp->data; 2238 leaf2 = leaf2_bp->data; 2239 ASSERT((leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)) && 2240 (leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC))); 2241 if ((be16_to_cpu(leaf1->hdr.count) > 0) && 2242 (be16_to_cpu(leaf2->hdr.count) > 0) && 2243 ((be32_to_cpu(leaf2->entries[0].hashval) < 2244 be32_to_cpu(leaf1->entries[0].hashval)) || 2245 (be32_to_cpu(leaf2->entries[ 2246 be16_to_cpu(leaf2->hdr.count)-1].hashval) < 2247 be32_to_cpu(leaf1->entries[ 2248 be16_to_cpu(leaf1->hdr.count)-1].hashval)))) { 2249 return(1); 2250 } 2251 return(0); 2252} 2253 2254/* 2255 * Pick up the last hashvalue from a leaf block. 2256 */ 2257xfs_dahash_t 2258xfs_attr_leaf_lasthash(xfs_dabuf_t *bp, int *count) 2259{ 2260 xfs_attr_leafblock_t *leaf; 2261 2262 leaf = bp->data; 2263 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 2264 if (count) 2265 *count = be16_to_cpu(leaf->hdr.count); 2266 if (!leaf->hdr.count) 2267 return(0); 2268 return be32_to_cpu(leaf->entries[be16_to_cpu(leaf->hdr.count)-1].hashval); 2269} 2270 2271/* 2272 * Calculate the number of bytes used to store the indicated attribute 2273 * (whether local or remote only calculate bytes in this block). 2274 */ 2275STATIC int 2276xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index) 2277{ 2278 xfs_attr_leaf_name_local_t *name_loc; 2279 xfs_attr_leaf_name_remote_t *name_rmt; 2280 int size; 2281 2282 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 2283 if (leaf->entries[index].flags & XFS_ATTR_LOCAL) { 2284 name_loc = xfs_attr_leaf_name_local(leaf, index); 2285 size = xfs_attr_leaf_entsize_local(name_loc->namelen, 2286 be16_to_cpu(name_loc->valuelen)); 2287 } else { 2288 name_rmt = xfs_attr_leaf_name_remote(leaf, index); 2289 size = xfs_attr_leaf_entsize_remote(name_rmt->namelen); 2290 } 2291 return(size); 2292} 2293 2294/* 2295 * Calculate the number of bytes that would be required to store the new 2296 * attribute (whether local or remote only calculate bytes in this block). 2297 * This routine decides as a side effect whether the attribute will be 2298 * a "local" or a "remote" attribute. 2299 */ 2300int 2301xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int *local) 2302{ 2303 int size; 2304 2305 size = xfs_attr_leaf_entsize_local(namelen, valuelen); 2306 if (size < xfs_attr_leaf_entsize_local_max(blocksize)) { 2307 if (local) { 2308 *local = 1; 2309 } 2310 } else { 2311 size = xfs_attr_leaf_entsize_remote(namelen); 2312 if (local) { 2313 *local = 0; 2314 } 2315 } 2316 return(size); 2317} 2318 2319/* 2320 * Copy out attribute list entries for attr_list(), for leaf attribute lists. 2321 */ 2322int 2323xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) 2324{ 2325 attrlist_cursor_kern_t *cursor; 2326 xfs_attr_leafblock_t *leaf; 2327 xfs_attr_leaf_entry_t *entry; 2328 int retval, i; 2329 2330 ASSERT(bp != NULL); 2331 leaf = bp->data; 2332 cursor = context->cursor; 2333 cursor->initted = 1; 2334 2335 trace_xfs_attr_list_leaf(context); 2336 2337 /* 2338 * Re-find our place in the leaf block if this is a new syscall. 2339 */ 2340 if (context->resynch) { 2341 entry = &leaf->entries[0]; 2342 for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { 2343 if (be32_to_cpu(entry->hashval) == cursor->hashval) { 2344 if (cursor->offset == context->dupcnt) { 2345 context->dupcnt = 0; 2346 break; 2347 } 2348 context->dupcnt++; 2349 } else if (be32_to_cpu(entry->hashval) > 2350 cursor->hashval) { 2351 context->dupcnt = 0; 2352 break; 2353 } 2354 } 2355 if (i == be16_to_cpu(leaf->hdr.count)) { 2356 trace_xfs_attr_list_notfound(context); 2357 return(0); 2358 } 2359 } else { 2360 entry = &leaf->entries[0]; 2361 i = 0; 2362 } 2363 context->resynch = 0; 2364 2365 /* 2366 * We have found our place, start copying out the new attributes. 2367 */ 2368 retval = 0; 2369 for ( ; (i < be16_to_cpu(leaf->hdr.count)); entry++, i++) { 2370 if (be32_to_cpu(entry->hashval) != cursor->hashval) { 2371 cursor->hashval = be32_to_cpu(entry->hashval); 2372 cursor->offset = 0; 2373 } 2374 2375 if (entry->flags & XFS_ATTR_INCOMPLETE) 2376 continue; /* skip incomplete entries */ 2377 2378 if (entry->flags & XFS_ATTR_LOCAL) { 2379 xfs_attr_leaf_name_local_t *name_loc = 2380 xfs_attr_leaf_name_local(leaf, i); 2381 2382 retval = context->put_listent(context, 2383 entry->flags, 2384 name_loc->nameval, 2385 (int)name_loc->namelen, 2386 be16_to_cpu(name_loc->valuelen), 2387 &name_loc->nameval[name_loc->namelen]); 2388 if (retval) 2389 return retval; 2390 } else { 2391 xfs_attr_leaf_name_remote_t *name_rmt = 2392 xfs_attr_leaf_name_remote(leaf, i); 2393 2394 int valuelen = be32_to_cpu(name_rmt->valuelen); 2395 2396 if (context->put_value) { 2397 xfs_da_args_t args; 2398 2399 memset((char *)&args, 0, sizeof(args)); 2400 args.dp = context->dp; 2401 args.whichfork = XFS_ATTR_FORK; 2402 args.valuelen = valuelen; 2403 args.value = kmem_alloc(valuelen, KM_SLEEP | KM_NOFS); 2404 args.rmtblkno = be32_to_cpu(name_rmt->valueblk); 2405 args.rmtblkcnt = XFS_B_TO_FSB(args.dp->i_mount, valuelen); 2406 retval = xfs_attr_rmtval_get(&args); 2407 if (retval) 2408 return retval; 2409 retval = context->put_listent(context, 2410 entry->flags, 2411 name_rmt->name, 2412 (int)name_rmt->namelen, 2413 valuelen, 2414 args.value); 2415 kmem_free(args.value); 2416 } else { 2417 retval = context->put_listent(context, 2418 entry->flags, 2419 name_rmt->name, 2420 (int)name_rmt->namelen, 2421 valuelen, 2422 NULL); 2423 } 2424 if (retval) 2425 return retval; 2426 } 2427 if (context->seen_enough) 2428 break; 2429 cursor->offset++; 2430 } 2431 trace_xfs_attr_list_leaf_end(context); 2432 return(retval); 2433} 2434 2435 2436/*======================================================================== 2437 * Manage the INCOMPLETE flag in a leaf entry 2438 *========================================================================*/ 2439 2440/* 2441 * Clear the INCOMPLETE flag on an entry in a leaf block. 2442 */ 2443int 2444xfs_attr_leaf_clearflag(xfs_da_args_t *args) 2445{ 2446 xfs_attr_leafblock_t *leaf; 2447 xfs_attr_leaf_entry_t *entry; 2448 xfs_attr_leaf_name_remote_t *name_rmt; 2449 xfs_dabuf_t *bp; 2450 int error; 2451#ifdef DEBUG 2452 xfs_attr_leaf_name_local_t *name_loc; 2453 int namelen; 2454 char *name; 2455#endif /* DEBUG */ 2456 2457 /* 2458 * Set up the operation. 2459 */ 2460 error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, 2461 XFS_ATTR_FORK); 2462 if (error) { 2463 return(error); 2464 } 2465 ASSERT(bp != NULL); 2466 2467 leaf = bp->data; 2468 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 2469 ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); 2470 ASSERT(args->index >= 0); 2471 entry = &leaf->entries[ args->index ]; 2472 ASSERT(entry->flags & XFS_ATTR_INCOMPLETE); 2473 2474#ifdef DEBUG 2475 if (entry->flags & XFS_ATTR_LOCAL) { 2476 name_loc = xfs_attr_leaf_name_local(leaf, args->index); 2477 namelen = name_loc->namelen; 2478 name = (char *)name_loc->nameval; 2479 } else { 2480 name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); 2481 namelen = name_rmt->namelen; 2482 name = (char *)name_rmt->name; 2483 } 2484 ASSERT(be32_to_cpu(entry->hashval) == args->hashval); 2485 ASSERT(namelen == args->namelen); 2486 ASSERT(memcmp(name, args->name, namelen) == 0); 2487#endif /* DEBUG */ 2488 2489 entry->flags &= ~XFS_ATTR_INCOMPLETE; 2490 xfs_da_log_buf(args->trans, bp, 2491 XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); 2492 2493 if (args->rmtblkno) { 2494 ASSERT((entry->flags & XFS_ATTR_LOCAL) == 0); 2495 name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); 2496 name_rmt->valueblk = cpu_to_be32(args->rmtblkno); 2497 name_rmt->valuelen = cpu_to_be32(args->valuelen); 2498 xfs_da_log_buf(args->trans, bp, 2499 XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); 2500 } 2501 xfs_da_buf_done(bp); 2502 2503 /* 2504 * Commit the flag value change and start the next trans in series. 2505 */ 2506 return xfs_trans_roll(&args->trans, args->dp); 2507} 2508 2509/* 2510 * Set the INCOMPLETE flag on an entry in a leaf block. 2511 */ 2512int 2513xfs_attr_leaf_setflag(xfs_da_args_t *args) 2514{ 2515 xfs_attr_leafblock_t *leaf; 2516 xfs_attr_leaf_entry_t *entry; 2517 xfs_attr_leaf_name_remote_t *name_rmt; 2518 xfs_dabuf_t *bp; 2519 int error; 2520 2521 /* 2522 * Set up the operation. 2523 */ 2524 error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, 2525 XFS_ATTR_FORK); 2526 if (error) { 2527 return(error); 2528 } 2529 ASSERT(bp != NULL); 2530 2531 leaf = bp->data; 2532 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 2533 ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); 2534 ASSERT(args->index >= 0); 2535 entry = &leaf->entries[ args->index ]; 2536 2537 ASSERT((entry->flags & XFS_ATTR_INCOMPLETE) == 0); 2538 entry->flags |= XFS_ATTR_INCOMPLETE; 2539 xfs_da_log_buf(args->trans, bp, 2540 XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); 2541 if ((entry->flags & XFS_ATTR_LOCAL) == 0) { 2542 name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); 2543 name_rmt->valueblk = 0; 2544 name_rmt->valuelen = 0; 2545 xfs_da_log_buf(args->trans, bp, 2546 XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); 2547 } 2548 xfs_da_buf_done(bp); 2549 2550 /* 2551 * Commit the flag value change and start the next trans in series. 2552 */ 2553 return xfs_trans_roll(&args->trans, args->dp); 2554} 2555 2556/* 2557 * In a single transaction, clear the INCOMPLETE flag on the leaf entry 2558 * given by args->blkno/index and set the INCOMPLETE flag on the leaf 2559 * entry given by args->blkno2/index2. 2560 * 2561 * Note that they could be in different blocks, or in the same block. 2562 */ 2563int 2564xfs_attr_leaf_flipflags(xfs_da_args_t *args) 2565{ 2566 xfs_attr_leafblock_t *leaf1, *leaf2; 2567 xfs_attr_leaf_entry_t *entry1, *entry2; 2568 xfs_attr_leaf_name_remote_t *name_rmt; 2569 xfs_dabuf_t *bp1, *bp2; 2570 int error; 2571#ifdef DEBUG 2572 xfs_attr_leaf_name_local_t *name_loc; 2573 int namelen1, namelen2; 2574 char *name1, *name2; 2575#endif /* DEBUG */ 2576 2577 /* 2578 * Read the block containing the "old" attr 2579 */ 2580 error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp1, 2581 XFS_ATTR_FORK); 2582 if (error) { 2583 return(error); 2584 } 2585 ASSERT(bp1 != NULL); 2586 2587 /* 2588 * Read the block containing the "new" attr, if it is different 2589 */ 2590 if (args->blkno2 != args->blkno) { 2591 error = xfs_da_read_buf(args->trans, args->dp, args->blkno2, 2592 -1, &bp2, XFS_ATTR_FORK); 2593 if (error) { 2594 return(error); 2595 } 2596 ASSERT(bp2 != NULL); 2597 } else { 2598 bp2 = bp1; 2599 } 2600 2601 leaf1 = bp1->data; 2602 ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 2603 ASSERT(args->index < be16_to_cpu(leaf1->hdr.count)); 2604 ASSERT(args->index >= 0); 2605 entry1 = &leaf1->entries[ args->index ]; 2606 2607 leaf2 = bp2->data; 2608 ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 2609 ASSERT(args->index2 < be16_to_cpu(leaf2->hdr.count)); 2610 ASSERT(args->index2 >= 0); 2611 entry2 = &leaf2->entries[ args->index2 ]; 2612 2613#ifdef DEBUG 2614 if (entry1->flags & XFS_ATTR_LOCAL) { 2615 name_loc = xfs_attr_leaf_name_local(leaf1, args->index); 2616 namelen1 = name_loc->namelen; 2617 name1 = (char *)name_loc->nameval; 2618 } else { 2619 name_rmt = xfs_attr_leaf_name_remote(leaf1, args->index); 2620 namelen1 = name_rmt->namelen; 2621 name1 = (char *)name_rmt->name; 2622 } 2623 if (entry2->flags & XFS_ATTR_LOCAL) { 2624 name_loc = xfs_attr_leaf_name_local(leaf2, args->index2); 2625 namelen2 = name_loc->namelen; 2626 name2 = (char *)name_loc->nameval; 2627 } else { 2628 name_rmt = xfs_attr_leaf_name_remote(leaf2, args->index2); 2629 namelen2 = name_rmt->namelen; 2630 name2 = (char *)name_rmt->name; 2631 } 2632 ASSERT(be32_to_cpu(entry1->hashval) == be32_to_cpu(entry2->hashval)); 2633 ASSERT(namelen1 == namelen2); 2634 ASSERT(memcmp(name1, name2, namelen1) == 0); 2635#endif /* DEBUG */ 2636 2637 ASSERT(entry1->flags & XFS_ATTR_INCOMPLETE); 2638 ASSERT((entry2->flags & XFS_ATTR_INCOMPLETE) == 0); 2639 2640 entry1->flags &= ~XFS_ATTR_INCOMPLETE; 2641 xfs_da_log_buf(args->trans, bp1, 2642 XFS_DA_LOGRANGE(leaf1, entry1, sizeof(*entry1))); 2643 if (args->rmtblkno) { 2644 ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0); 2645 name_rmt = xfs_attr_leaf_name_remote(leaf1, args->index); 2646 name_rmt->valueblk = cpu_to_be32(args->rmtblkno); 2647 name_rmt->valuelen = cpu_to_be32(args->valuelen); 2648 xfs_da_log_buf(args->trans, bp1, 2649 XFS_DA_LOGRANGE(leaf1, name_rmt, sizeof(*name_rmt))); 2650 } 2651 2652 entry2->flags |= XFS_ATTR_INCOMPLETE; 2653 xfs_da_log_buf(args->trans, bp2, 2654 XFS_DA_LOGRANGE(leaf2, entry2, sizeof(*entry2))); 2655 if ((entry2->flags & XFS_ATTR_LOCAL) == 0) { 2656 name_rmt = xfs_attr_leaf_name_remote(leaf2, args->index2); 2657 name_rmt->valueblk = 0; 2658 name_rmt->valuelen = 0; 2659 xfs_da_log_buf(args->trans, bp2, 2660 XFS_DA_LOGRANGE(leaf2, name_rmt, sizeof(*name_rmt))); 2661 } 2662 xfs_da_buf_done(bp1); 2663 if (bp1 != bp2) 2664 xfs_da_buf_done(bp2); 2665 2666 /* 2667 * Commit the flag value change and start the next trans in series. 2668 */ 2669 error = xfs_trans_roll(&args->trans, args->dp); 2670 2671 return(error); 2672} 2673 2674/*======================================================================== 2675 * Indiscriminately delete the entire attribute fork 2676 *========================================================================*/ 2677 2678/* 2679 * Recurse (gasp!) through the attribute nodes until we find leaves. 2680 * We're doing a depth-first traversal in order to invalidate everything. 2681 */ 2682int 2683xfs_attr_root_inactive(xfs_trans_t **trans, xfs_inode_t *dp) 2684{ 2685 xfs_da_blkinfo_t *info; 2686 xfs_daddr_t blkno; 2687 xfs_dabuf_t *bp; 2688 int error; 2689 2690 /* 2691 * Read block 0 to see what we have to work with. 2692 * We only get here if we have extents, since we remove 2693 * the extents in reverse order the extent containing 2694 * block 0 must still be there. 2695 */ 2696 error = xfs_da_read_buf(*trans, dp, 0, -1, &bp, XFS_ATTR_FORK); 2697 if (error) 2698 return(error); 2699 blkno = xfs_da_blkno(bp); 2700 2701 /* 2702 * Invalidate the tree, even if the "tree" is only a single leaf block. 2703 * This is a depth-first traversal! 2704 */ 2705 info = bp->data; 2706 if (info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC)) { 2707 error = xfs_attr_node_inactive(trans, dp, bp, 1); 2708 } else if (info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)) { 2709 error = xfs_attr_leaf_inactive(trans, dp, bp); 2710 } else { 2711 error = XFS_ERROR(EIO); 2712 xfs_da_brelse(*trans, bp); 2713 } 2714 if (error) 2715 return(error); 2716 2717 /* 2718 * Invalidate the incore copy of the root block. 2719 */ 2720 error = xfs_da_get_buf(*trans, dp, 0, blkno, &bp, XFS_ATTR_FORK); 2721 if (error) 2722 return(error); 2723 xfs_da_binval(*trans, bp); /* remove from cache */ 2724 /* 2725 * Commit the invalidate and start the next transaction. 2726 */ 2727 error = xfs_trans_roll(trans, dp); 2728 2729 return (error); 2730} 2731 2732/* 2733 * Recurse (gasp!) through the attribute nodes until we find leaves. 2734 * We're doing a depth-first traversal in order to invalidate everything. 2735 */ 2736STATIC int 2737xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp, 2738 int level) 2739{ 2740 xfs_da_blkinfo_t *info; 2741 xfs_da_intnode_t *node; 2742 xfs_dablk_t child_fsb; 2743 xfs_daddr_t parent_blkno, child_blkno; 2744 int error, count, i; 2745 xfs_dabuf_t *child_bp; 2746 2747 /* 2748 * Since this code is recursive (gasp!) we must protect ourselves. 2749 */ 2750 if (level > XFS_DA_NODE_MAXDEPTH) { 2751 xfs_da_brelse(*trans, bp); /* no locks for later trans */ 2752 return(XFS_ERROR(EIO)); 2753 } 2754 2755 node = bp->data; 2756 ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); 2757 parent_blkno = xfs_da_blkno(bp); /* save for re-read later */ 2758 count = be16_to_cpu(node->hdr.count); 2759 if (!count) { 2760 xfs_da_brelse(*trans, bp); 2761 return(0); 2762 } 2763 child_fsb = be32_to_cpu(node->btree[0].before); 2764 xfs_da_brelse(*trans, bp); /* no locks for later trans */ 2765 2766 /* 2767 * If this is the node level just above the leaves, simply loop 2768 * over the leaves removing all of them. If this is higher up 2769 * in the tree, recurse downward. 2770 */ 2771 for (i = 0; i < count; i++) { 2772 /* 2773 * Read the subsidiary block to see what we have to work with. 2774 * Don't do this in a transaction. This is a depth-first 2775 * traversal of the tree so we may deal with many blocks 2776 * before we come back to this one. 2777 */ 2778 error = xfs_da_read_buf(*trans, dp, child_fsb, -2, &child_bp, 2779 XFS_ATTR_FORK); 2780 if (error) 2781 return(error); 2782 if (child_bp) { 2783 /* save for re-read later */ 2784 child_blkno = xfs_da_blkno(child_bp); 2785 2786 /* 2787 * Invalidate the subtree, however we have to. 2788 */ 2789 info = child_bp->data; 2790 if (info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC)) { 2791 error = xfs_attr_node_inactive(trans, dp, 2792 child_bp, level+1); 2793 } else if (info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)) { 2794 error = xfs_attr_leaf_inactive(trans, dp, 2795 child_bp); 2796 } else { 2797 error = XFS_ERROR(EIO); 2798 xfs_da_brelse(*trans, child_bp); 2799 } 2800 if (error) 2801 return(error); 2802 2803 /* 2804 * Remove the subsidiary block from the cache 2805 * and from the log. 2806 */ 2807 error = xfs_da_get_buf(*trans, dp, 0, child_blkno, 2808 &child_bp, XFS_ATTR_FORK); 2809 if (error) 2810 return(error); 2811 xfs_da_binval(*trans, child_bp); 2812 } 2813 2814 /* 2815 * If we're not done, re-read the parent to get the next 2816 * child block number. 2817 */ 2818 if ((i+1) < count) { 2819 error = xfs_da_read_buf(*trans, dp, 0, parent_blkno, 2820 &bp, XFS_ATTR_FORK); 2821 if (error) 2822 return(error); 2823 child_fsb = be32_to_cpu(node->btree[i+1].before); 2824 xfs_da_brelse(*trans, bp); 2825 } 2826 /* 2827 * Atomically commit the whole invalidate stuff. 2828 */ 2829 error = xfs_trans_roll(trans, dp); 2830 if (error) 2831 return (error); 2832 } 2833 2834 return(0); 2835} 2836 2837/* 2838 * Invalidate all of the "remote" value regions pointed to by a particular 2839 * leaf block. 2840 * Note that we must release the lock on the buffer so that we are not 2841 * caught holding something that the logging code wants to flush to disk. 2842 */ 2843STATIC int 2844xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp) 2845{ 2846 xfs_attr_leafblock_t *leaf; 2847 xfs_attr_leaf_entry_t *entry; 2848 xfs_attr_leaf_name_remote_t *name_rmt; 2849 xfs_attr_inactive_list_t *list, *lp; 2850 int error, count, size, tmp, i; 2851 2852 leaf = bp->data; 2853 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 2854 2855 /* 2856 * Count the number of "remote" value extents. 2857 */ 2858 count = 0; 2859 entry = &leaf->entries[0]; 2860 for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { 2861 if (be16_to_cpu(entry->nameidx) && 2862 ((entry->flags & XFS_ATTR_LOCAL) == 0)) { 2863 name_rmt = xfs_attr_leaf_name_remote(leaf, i); 2864 if (name_rmt->valueblk) 2865 count++; 2866 } 2867 } 2868 2869 /* 2870 * If there are no "remote" values, we're done. 2871 */ 2872 if (count == 0) { 2873 xfs_da_brelse(*trans, bp); 2874 return(0); 2875 } 2876 2877 /* 2878 * Allocate storage for a list of all the "remote" value extents. 2879 */ 2880 size = count * sizeof(xfs_attr_inactive_list_t); 2881 list = (xfs_attr_inactive_list_t *)kmem_alloc(size, KM_SLEEP); 2882 2883 /* 2884 * Identify each of the "remote" value extents. 2885 */ 2886 lp = list; 2887 entry = &leaf->entries[0]; 2888 for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { 2889 if (be16_to_cpu(entry->nameidx) && 2890 ((entry->flags & XFS_ATTR_LOCAL) == 0)) { 2891 name_rmt = xfs_attr_leaf_name_remote(leaf, i); 2892 if (name_rmt->valueblk) { 2893 lp->valueblk = be32_to_cpu(name_rmt->valueblk); 2894 lp->valuelen = XFS_B_TO_FSB(dp->i_mount, 2895 be32_to_cpu(name_rmt->valuelen)); 2896 lp++; 2897 } 2898 } 2899 } 2900 xfs_da_brelse(*trans, bp); /* unlock for trans. in freextent() */ 2901 2902 /* 2903 * Invalidate each of the "remote" value extents. 2904 */ 2905 error = 0; 2906 for (lp = list, i = 0; i < count; i++, lp++) { 2907 tmp = xfs_attr_leaf_freextent(trans, dp, 2908 lp->valueblk, lp->valuelen); 2909 2910 if (error == 0) 2911 error = tmp; /* save only the 1st errno */ 2912 } 2913 2914 kmem_free((xfs_caddr_t)list); 2915 return(error); 2916} 2917 2918/* 2919 * Look at all the extents for this logical region, 2920 * invalidate any buffers that are incore/in transactions. 2921 */ 2922STATIC int 2923xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp, 2924 xfs_dablk_t blkno, int blkcnt) 2925{ 2926 xfs_bmbt_irec_t map; 2927 xfs_dablk_t tblkno; 2928 int tblkcnt, dblkcnt, nmap, error; 2929 xfs_daddr_t dblkno; 2930 xfs_buf_t *bp; 2931 2932 /* 2933 * Roll through the "value", invalidating the attribute value's 2934 * blocks. 2935 */ 2936 tblkno = blkno; 2937 tblkcnt = blkcnt; 2938 while (tblkcnt > 0) { 2939 /* 2940 * Try to remember where we decided to put the value. 2941 */ 2942 nmap = 1; 2943 error = xfs_bmapi_read(dp, (xfs_fileoff_t)tblkno, tblkcnt, 2944 &map, &nmap, XFS_BMAPI_ATTRFORK); 2945 if (error) { 2946 return(error); 2947 } 2948 ASSERT(nmap == 1); 2949 ASSERT(map.br_startblock != DELAYSTARTBLOCK); 2950 2951 /* 2952 * If it's a hole, these are already unmapped 2953 * so there's nothing to invalidate. 2954 */ 2955 if (map.br_startblock != HOLESTARTBLOCK) { 2956 2957 dblkno = XFS_FSB_TO_DADDR(dp->i_mount, 2958 map.br_startblock); 2959 dblkcnt = XFS_FSB_TO_BB(dp->i_mount, 2960 map.br_blockcount); 2961 bp = xfs_trans_get_buf(*trans, 2962 dp->i_mount->m_ddev_targp, 2963 dblkno, dblkcnt, XBF_LOCK); 2964 if (!bp) 2965 return ENOMEM; 2966 xfs_trans_binval(*trans, bp); 2967 /* 2968 * Roll to next transaction. 2969 */ 2970 error = xfs_trans_roll(trans, dp); 2971 if (error) 2972 return (error); 2973 } 2974 2975 tblkno += map.br_blockcount; 2976 tblkcnt -= map.br_blockcount; 2977 } 2978 2979 return(0); 2980}