/linux-2.6.33/kernel/linux-2.6.33/fs/xfs/xfs_attr.c
C | 2265 lines | 1418 code | 234 blank | 613 comment | 329 complexity | b3505562027595ed7bdd046256a76f02 MD5 | raw file
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 19#include "xfs.h" 20#include "xfs_fs.h" 21#include "xfs_types.h" 22#include "xfs_bit.h" 23#include "xfs_log.h" 24#include "xfs_inum.h" 25#include "xfs_trans.h" 26#include "xfs_sb.h" 27#include "xfs_ag.h" 28#include "xfs_dir2.h" 29#include "xfs_dmapi.h" 30#include "xfs_mount.h" 31#include "xfs_da_btree.h" 32#include "xfs_bmap_btree.h" 33#include "xfs_alloc_btree.h" 34#include "xfs_ialloc_btree.h" 35#include "xfs_dir2_sf.h" 36#include "xfs_attr_sf.h" 37#include "xfs_dinode.h" 38#include "xfs_inode.h" 39#include "xfs_alloc.h" 40#include "xfs_btree.h" 41#include "xfs_inode_item.h" 42#include "xfs_bmap.h" 43#include "xfs_attr.h" 44#include "xfs_attr_leaf.h" 45#include "xfs_error.h" 46#include "xfs_quota.h" 47#include "xfs_trans_space.h" 48#include "xfs_rw.h" 49#include "xfs_vnodeops.h" 50#include "xfs_trace.h" 51 52/* 53 * xfs_attr.c 54 * 55 * Provide the external interfaces to manage attribute lists. 56 */ 57 58/*======================================================================== 59 * Function prototypes for the kernel. 60 *========================================================================*/ 61 62/* 63 * Internal routines when attribute list fits inside the inode. 64 */ 65STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args); 66 67/* 68 * Internal routines when attribute list is one block. 69 */ 70STATIC int xfs_attr_leaf_get(xfs_da_args_t *args); 71STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args); 72STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args); 73STATIC int xfs_attr_leaf_list(xfs_attr_list_context_t *context); 74 75/* 76 * Internal routines when attribute list is more than one block. 77 */ 78STATIC int xfs_attr_node_get(xfs_da_args_t *args); 79STATIC int xfs_attr_node_addname(xfs_da_args_t *args); 80STATIC int xfs_attr_node_removename(xfs_da_args_t *args); 81STATIC int xfs_attr_node_list(xfs_attr_list_context_t *context); 82STATIC int xfs_attr_fillstate(xfs_da_state_t *state); 83STATIC int xfs_attr_refillstate(xfs_da_state_t *state); 84 85/* 86 * Routines to manipulate out-of-line attribute values. 87 */ 88STATIC int xfs_attr_rmtval_set(xfs_da_args_t *args); 89STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args); 90 91#define ATTR_RMTVALUE_MAPSIZE 1 /* # of map entries at once */ 92 93STATIC int 94xfs_attr_name_to_xname( 95 struct xfs_name *xname, 96 const char *aname) 97{ 98 if (!aname) 99 return EINVAL; 100 xname->name = aname; 101 xname->len = strlen(aname); 102 if (xname->len >= MAXNAMELEN) 103 return EFAULT; /* match IRIX behaviour */ 104 105 return 0; 106} 107 108STATIC int 109xfs_inode_hasattr( 110 struct xfs_inode *ip) 111{ 112 if (!XFS_IFORK_Q(ip) || 113 (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && 114 ip->i_d.di_anextents == 0)) 115 return 0; 116 return 1; 117} 118 119/*======================================================================== 120 * Overall external interface routines. 121 *========================================================================*/ 122 123STATIC int 124xfs_attr_get_int( 125 struct xfs_inode *ip, 126 struct xfs_name *name, 127 char *value, 128 int *valuelenp, 129 int flags) 130{ 131 xfs_da_args_t args; 132 int error; 133 134 if (!xfs_inode_hasattr(ip)) 135 return ENOATTR; 136 137 /* 138 * Fill in the arg structure for this request. 139 */ 140 memset((char *)&args, 0, sizeof(args)); 141 args.name = name->name; 142 args.namelen = name->len; 143 args.value = value; 144 args.valuelen = *valuelenp; 145 args.flags = flags; 146 args.hashval = xfs_da_hashname(args.name, args.namelen); 147 args.dp = ip; 148 args.whichfork = XFS_ATTR_FORK; 149 150 /* 151 * Decide on what work routines to call based on the inode size. 152 */ 153 if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { 154 error = xfs_attr_shortform_getvalue(&args); 155 } else if (xfs_bmap_one_block(ip, XFS_ATTR_FORK)) { 156 error = xfs_attr_leaf_get(&args); 157 } else { 158 error = xfs_attr_node_get(&args); 159 } 160 161 /* 162 * Return the number of bytes in the value to the caller. 163 */ 164 *valuelenp = args.valuelen; 165 166 if (error == EEXIST) 167 error = 0; 168 return(error); 169} 170 171int 172xfs_attr_get( 173 xfs_inode_t *ip, 174 const char *name, 175 char *value, 176 int *valuelenp, 177 int flags) 178{ 179 int error; 180 struct xfs_name xname; 181 182 XFS_STATS_INC(xs_attr_get); 183 184 if (XFS_FORCED_SHUTDOWN(ip->i_mount)) 185 return(EIO); 186 187 error = xfs_attr_name_to_xname(&xname, name); 188 if (error) 189 return error; 190 191 xfs_ilock(ip, XFS_ILOCK_SHARED); 192 error = xfs_attr_get_int(ip, &xname, value, valuelenp, flags); 193 xfs_iunlock(ip, XFS_ILOCK_SHARED); 194 return(error); 195} 196 197/* 198 * Calculate how many blocks we need for the new attribute, 199 */ 200int 201xfs_attr_calc_size( 202 struct xfs_inode *ip, 203 int namelen, 204 int valuelen, 205 int *local) 206{ 207 struct xfs_mount *mp = ip->i_mount; 208 int size; 209 int nblks; 210 211 /* 212 * Determine space new attribute will use, and if it would be 213 * "local" or "remote" (note: local != inline). 214 */ 215 size = xfs_attr_leaf_newentsize(namelen, valuelen, 216 mp->m_sb.sb_blocksize, local); 217 218 nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); 219 if (*local) { 220 if (size > (mp->m_sb.sb_blocksize >> 1)) { 221 /* Double split possible */ 222 nblks *= 2; 223 } 224 } else { 225 /* 226 * Out of line attribute, cannot double split, but 227 * make room for the attribute value itself. 228 */ 229 uint dblocks = XFS_B_TO_FSB(mp, valuelen); 230 nblks += dblocks; 231 nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK); 232 } 233 234 return nblks; 235} 236 237STATIC int 238xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name, 239 char *value, int valuelen, int flags) 240{ 241 xfs_da_args_t args; 242 xfs_fsblock_t firstblock; 243 xfs_bmap_free_t flist; 244 int error, err2, committed; 245 xfs_mount_t *mp = dp->i_mount; 246 int rsvd = (flags & ATTR_ROOT) != 0; 247 int local; 248 249 /* 250 * Attach the dquots to the inode. 251 */ 252 error = xfs_qm_dqattach(dp, 0); 253 if (error) 254 return error; 255 256 /* 257 * If the inode doesn't have an attribute fork, add one. 258 * (inode must not be locked when we call this routine) 259 */ 260 if (XFS_IFORK_Q(dp) == 0) { 261 int sf_size = sizeof(xfs_attr_sf_hdr_t) + 262 XFS_ATTR_SF_ENTSIZE_BYNAME(name->len, valuelen); 263 264 if ((error = xfs_bmap_add_attrfork(dp, sf_size, rsvd))) 265 return(error); 266 } 267 268 /* 269 * Fill in the arg structure for this request. 270 */ 271 memset((char *)&args, 0, sizeof(args)); 272 args.name = name->name; 273 args.namelen = name->len; 274 args.value = value; 275 args.valuelen = valuelen; 276 args.flags = flags; 277 args.hashval = xfs_da_hashname(args.name, args.namelen); 278 args.dp = dp; 279 args.firstblock = &firstblock; 280 args.flist = &flist; 281 args.whichfork = XFS_ATTR_FORK; 282 args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; 283 284 /* Size is now blocks for attribute data */ 285 args.total = xfs_attr_calc_size(dp, name->len, valuelen, &local); 286 287 /* 288 * Start our first transaction of the day. 289 * 290 * All future transactions during this code must be "chained" off 291 * this one via the trans_dup() call. All transactions will contain 292 * the inode, and the inode will always be marked with trans_ihold(). 293 * Since the inode will be locked in all transactions, we must log 294 * the inode in every transaction to let it float upward through 295 * the log. 296 */ 297 args.trans = xfs_trans_alloc(mp, XFS_TRANS_ATTR_SET); 298 299 /* 300 * Root fork attributes can use reserved data blocks for this 301 * operation if necessary 302 */ 303 304 if (rsvd) 305 args.trans->t_flags |= XFS_TRANS_RESERVE; 306 307 if ((error = xfs_trans_reserve(args.trans, args.total, 308 XFS_ATTRSET_LOG_RES(mp, args.total), 0, 309 XFS_TRANS_PERM_LOG_RES, XFS_ATTRSET_LOG_COUNT))) { 310 xfs_trans_cancel(args.trans, 0); 311 return(error); 312 } 313 xfs_ilock(dp, XFS_ILOCK_EXCL); 314 315 error = xfs_trans_reserve_quota_nblks(args.trans, dp, args.total, 0, 316 rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : 317 XFS_QMOPT_RES_REGBLKS); 318 if (error) { 319 xfs_iunlock(dp, XFS_ILOCK_EXCL); 320 xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES); 321 return (error); 322 } 323 324 xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL); 325 xfs_trans_ihold(args.trans, dp); 326 327 /* 328 * If the attribute list is non-existent or a shortform list, 329 * upgrade it to a single-leaf-block attribute list. 330 */ 331 if ((dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) || 332 ((dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) && 333 (dp->i_d.di_anextents == 0))) { 334 335 /* 336 * Build initial attribute list (if required). 337 */ 338 if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) 339 xfs_attr_shortform_create(&args); 340 341 /* 342 * Try to add the attr to the attribute list in 343 * the inode. 344 */ 345 error = xfs_attr_shortform_addname(&args); 346 if (error != ENOSPC) { 347 /* 348 * Commit the shortform mods, and we're done. 349 * NOTE: this is also the error path (EEXIST, etc). 350 */ 351 ASSERT(args.trans != NULL); 352 353 /* 354 * If this is a synchronous mount, make sure that 355 * the transaction goes to disk before returning 356 * to the user. 357 */ 358 if (mp->m_flags & XFS_MOUNT_WSYNC) { 359 xfs_trans_set_sync(args.trans); 360 } 361 err2 = xfs_trans_commit(args.trans, 362 XFS_TRANS_RELEASE_LOG_RES); 363 xfs_iunlock(dp, XFS_ILOCK_EXCL); 364 365 /* 366 * Hit the inode change time. 367 */ 368 if (!error && (flags & ATTR_KERNOTIME) == 0) { 369 xfs_ichgtime(dp, XFS_ICHGTIME_CHG); 370 } 371 return(error == 0 ? err2 : error); 372 } 373 374 /* 375 * It won't fit in the shortform, transform to a leaf block. 376 * GROT: another possible req'mt for a double-split btree op. 377 */ 378 xfs_bmap_init(args.flist, args.firstblock); 379 error = xfs_attr_shortform_to_leaf(&args); 380 if (!error) { 381 error = xfs_bmap_finish(&args.trans, args.flist, 382 &committed); 383 } 384 if (error) { 385 ASSERT(committed); 386 args.trans = NULL; 387 xfs_bmap_cancel(&flist); 388 goto out; 389 } 390 391 /* 392 * bmap_finish() may have committed the last trans and started 393 * a new one. We need the inode to be in all transactions. 394 */ 395 if (committed) { 396 xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL); 397 xfs_trans_ihold(args.trans, dp); 398 } 399 400 /* 401 * Commit the leaf transformation. We'll need another (linked) 402 * transaction to add the new attribute to the leaf. 403 */ 404 405 error = xfs_trans_roll(&args.trans, dp); 406 if (error) 407 goto out; 408 409 } 410 411 if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { 412 error = xfs_attr_leaf_addname(&args); 413 } else { 414 error = xfs_attr_node_addname(&args); 415 } 416 if (error) { 417 goto out; 418 } 419 420 /* 421 * If this is a synchronous mount, make sure that the 422 * transaction goes to disk before returning to the user. 423 */ 424 if (mp->m_flags & XFS_MOUNT_WSYNC) { 425 xfs_trans_set_sync(args.trans); 426 } 427 428 /* 429 * Commit the last in the sequence of transactions. 430 */ 431 xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE); 432 error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); 433 xfs_iunlock(dp, XFS_ILOCK_EXCL); 434 435 /* 436 * Hit the inode change time. 437 */ 438 if (!error && (flags & ATTR_KERNOTIME) == 0) { 439 xfs_ichgtime(dp, XFS_ICHGTIME_CHG); 440 } 441 442 return(error); 443 444out: 445 if (args.trans) 446 xfs_trans_cancel(args.trans, 447 XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); 448 xfs_iunlock(dp, XFS_ILOCK_EXCL); 449 return(error); 450} 451 452int 453xfs_attr_set( 454 xfs_inode_t *dp, 455 const char *name, 456 char *value, 457 int valuelen, 458 int flags) 459{ 460 int error; 461 struct xfs_name xname; 462 463 XFS_STATS_INC(xs_attr_set); 464 465 if (XFS_FORCED_SHUTDOWN(dp->i_mount)) 466 return (EIO); 467 468 error = xfs_attr_name_to_xname(&xname, name); 469 if (error) 470 return error; 471 472 return xfs_attr_set_int(dp, &xname, value, valuelen, flags); 473} 474 475/* 476 * Generic handler routine to remove a name from an attribute list. 477 * Transitions attribute list from Btree to shortform as necessary. 478 */ 479STATIC int 480xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) 481{ 482 xfs_da_args_t args; 483 xfs_fsblock_t firstblock; 484 xfs_bmap_free_t flist; 485 int error; 486 xfs_mount_t *mp = dp->i_mount; 487 488 /* 489 * Fill in the arg structure for this request. 490 */ 491 memset((char *)&args, 0, sizeof(args)); 492 args.name = name->name; 493 args.namelen = name->len; 494 args.flags = flags; 495 args.hashval = xfs_da_hashname(args.name, args.namelen); 496 args.dp = dp; 497 args.firstblock = &firstblock; 498 args.flist = &flist; 499 args.total = 0; 500 args.whichfork = XFS_ATTR_FORK; 501 502 /* 503 * Attach the dquots to the inode. 504 */ 505 error = xfs_qm_dqattach(dp, 0); 506 if (error) 507 return error; 508 509 /* 510 * Start our first transaction of the day. 511 * 512 * All future transactions during this code must be "chained" off 513 * this one via the trans_dup() call. All transactions will contain 514 * the inode, and the inode will always be marked with trans_ihold(). 515 * Since the inode will be locked in all transactions, we must log 516 * the inode in every transaction to let it float upward through 517 * the log. 518 */ 519 args.trans = xfs_trans_alloc(mp, XFS_TRANS_ATTR_RM); 520 521 /* 522 * Root fork attributes can use reserved data blocks for this 523 * operation if necessary 524 */ 525 526 if (flags & ATTR_ROOT) 527 args.trans->t_flags |= XFS_TRANS_RESERVE; 528 529 if ((error = xfs_trans_reserve(args.trans, 530 XFS_ATTRRM_SPACE_RES(mp), 531 XFS_ATTRRM_LOG_RES(mp), 532 0, XFS_TRANS_PERM_LOG_RES, 533 XFS_ATTRRM_LOG_COUNT))) { 534 xfs_trans_cancel(args.trans, 0); 535 return(error); 536 } 537 538 xfs_ilock(dp, XFS_ILOCK_EXCL); 539 /* 540 * No need to make quota reservations here. We expect to release some 541 * blocks not allocate in the common case. 542 */ 543 xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL); 544 xfs_trans_ihold(args.trans, dp); 545 546 /* 547 * Decide on what work routines to call based on the inode size. 548 */ 549 if (!xfs_inode_hasattr(dp)) { 550 error = XFS_ERROR(ENOATTR); 551 goto out; 552 } 553 if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { 554 ASSERT(dp->i_afp->if_flags & XFS_IFINLINE); 555 error = xfs_attr_shortform_remove(&args); 556 if (error) { 557 goto out; 558 } 559 } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { 560 error = xfs_attr_leaf_removename(&args); 561 } else { 562 error = xfs_attr_node_removename(&args); 563 } 564 if (error) { 565 goto out; 566 } 567 568 /* 569 * If this is a synchronous mount, make sure that the 570 * transaction goes to disk before returning to the user. 571 */ 572 if (mp->m_flags & XFS_MOUNT_WSYNC) { 573 xfs_trans_set_sync(args.trans); 574 } 575 576 /* 577 * Commit the last in the sequence of transactions. 578 */ 579 xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE); 580 error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); 581 xfs_iunlock(dp, XFS_ILOCK_EXCL); 582 583 /* 584 * Hit the inode change time. 585 */ 586 if (!error && (flags & ATTR_KERNOTIME) == 0) { 587 xfs_ichgtime(dp, XFS_ICHGTIME_CHG); 588 } 589 590 return(error); 591 592out: 593 if (args.trans) 594 xfs_trans_cancel(args.trans, 595 XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); 596 xfs_iunlock(dp, XFS_ILOCK_EXCL); 597 return(error); 598} 599 600int 601xfs_attr_remove( 602 xfs_inode_t *dp, 603 const char *name, 604 int flags) 605{ 606 int error; 607 struct xfs_name xname; 608 609 XFS_STATS_INC(xs_attr_remove); 610 611 if (XFS_FORCED_SHUTDOWN(dp->i_mount)) 612 return (EIO); 613 614 error = xfs_attr_name_to_xname(&xname, name); 615 if (error) 616 return error; 617 618 xfs_ilock(dp, XFS_ILOCK_SHARED); 619 if (!xfs_inode_hasattr(dp)) { 620 xfs_iunlock(dp, XFS_ILOCK_SHARED); 621 return XFS_ERROR(ENOATTR); 622 } 623 xfs_iunlock(dp, XFS_ILOCK_SHARED); 624 625 return xfs_attr_remove_int(dp, &xname, flags); 626} 627 628int 629xfs_attr_list_int(xfs_attr_list_context_t *context) 630{ 631 int error; 632 xfs_inode_t *dp = context->dp; 633 634 XFS_STATS_INC(xs_attr_list); 635 636 if (XFS_FORCED_SHUTDOWN(dp->i_mount)) 637 return EIO; 638 639 xfs_ilock(dp, XFS_ILOCK_SHARED); 640 641 /* 642 * Decide on what work routines to call based on the inode size. 643 */ 644 if (!xfs_inode_hasattr(dp)) { 645 error = 0; 646 } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { 647 error = xfs_attr_shortform_list(context); 648 } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { 649 error = xfs_attr_leaf_list(context); 650 } else { 651 error = xfs_attr_node_list(context); 652 } 653 654 xfs_iunlock(dp, XFS_ILOCK_SHARED); 655 656 return error; 657} 658 659#define ATTR_ENTBASESIZE /* minimum bytes used by an attr */ \ 660 (((struct attrlist_ent *) 0)->a_name - (char *) 0) 661#define ATTR_ENTSIZE(namelen) /* actual bytes used by an attr */ \ 662 ((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(u_int32_t)-1) \ 663 & ~(sizeof(u_int32_t)-1)) 664 665/* 666 * Format an attribute and copy it out to the user's buffer. 667 * Take care to check values and protect against them changing later, 668 * we may be reading them directly out of a user buffer. 669 */ 670/*ARGSUSED*/ 671STATIC int 672xfs_attr_put_listent(xfs_attr_list_context_t *context, int flags, 673 char *name, int namelen, 674 int valuelen, char *value) 675{ 676 struct attrlist *alist = (struct attrlist *)context->alist; 677 attrlist_ent_t *aep; 678 int arraytop; 679 680 ASSERT(!(context->flags & ATTR_KERNOVAL)); 681 ASSERT(context->count >= 0); 682 ASSERT(context->count < (ATTR_MAX_VALUELEN/8)); 683 ASSERT(context->firstu >= sizeof(*alist)); 684 ASSERT(context->firstu <= context->bufsize); 685 686 /* 687 * Only list entries in the right namespace. 688 */ 689 if (((context->flags & ATTR_SECURE) == 0) != 690 ((flags & XFS_ATTR_SECURE) == 0)) 691 return 0; 692 if (((context->flags & ATTR_ROOT) == 0) != 693 ((flags & XFS_ATTR_ROOT) == 0)) 694 return 0; 695 696 arraytop = sizeof(*alist) + 697 context->count * sizeof(alist->al_offset[0]); 698 context->firstu -= ATTR_ENTSIZE(namelen); 699 if (context->firstu < arraytop) { 700 trace_xfs_attr_list_full(context); 701 alist->al_more = 1; 702 context->seen_enough = 1; 703 return 1; 704 } 705 706 aep = (attrlist_ent_t *)&context->alist[context->firstu]; 707 aep->a_valuelen = valuelen; 708 memcpy(aep->a_name, name, namelen); 709 aep->a_name[namelen] = 0; 710 alist->al_offset[context->count++] = context->firstu; 711 alist->al_count = context->count; 712 trace_xfs_attr_list_add(context); 713 return 0; 714} 715 716/* 717 * Generate a list of extended attribute names and optionally 718 * also value lengths. Positive return value follows the XFS 719 * convention of being an error, zero or negative return code 720 * is the length of the buffer returned (negated), indicating 721 * success. 722 */ 723int 724xfs_attr_list( 725 xfs_inode_t *dp, 726 char *buffer, 727 int bufsize, 728 int flags, 729 attrlist_cursor_kern_t *cursor) 730{ 731 xfs_attr_list_context_t context; 732 struct attrlist *alist; 733 int error; 734 735 /* 736 * Validate the cursor. 737 */ 738 if (cursor->pad1 || cursor->pad2) 739 return(XFS_ERROR(EINVAL)); 740 if ((cursor->initted == 0) && 741 (cursor->hashval || cursor->blkno || cursor->offset)) 742 return XFS_ERROR(EINVAL); 743 744 /* 745 * Check for a properly aligned buffer. 746 */ 747 if (((long)buffer) & (sizeof(int)-1)) 748 return XFS_ERROR(EFAULT); 749 if (flags & ATTR_KERNOVAL) 750 bufsize = 0; 751 752 /* 753 * Initialize the output buffer. 754 */ 755 memset(&context, 0, sizeof(context)); 756 context.dp = dp; 757 context.cursor = cursor; 758 context.resynch = 1; 759 context.flags = flags; 760 context.alist = buffer; 761 context.bufsize = (bufsize & ~(sizeof(int)-1)); /* align */ 762 context.firstu = context.bufsize; 763 context.put_listent = xfs_attr_put_listent; 764 765 alist = (struct attrlist *)context.alist; 766 alist->al_count = 0; 767 alist->al_more = 0; 768 alist->al_offset[0] = context.bufsize; 769 770 error = xfs_attr_list_int(&context); 771 ASSERT(error >= 0); 772 return error; 773} 774 775int /* error */ 776xfs_attr_inactive(xfs_inode_t *dp) 777{ 778 xfs_trans_t *trans; 779 xfs_mount_t *mp; 780 int error; 781 782 mp = dp->i_mount; 783 ASSERT(! XFS_NOT_DQATTACHED(mp, dp)); 784 785 xfs_ilock(dp, XFS_ILOCK_SHARED); 786 if (!xfs_inode_hasattr(dp) || 787 dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { 788 xfs_iunlock(dp, XFS_ILOCK_SHARED); 789 return 0; 790 } 791 xfs_iunlock(dp, XFS_ILOCK_SHARED); 792 793 /* 794 * Start our first transaction of the day. 795 * 796 * All future transactions during this code must be "chained" off 797 * this one via the trans_dup() call. All transactions will contain 798 * the inode, and the inode will always be marked with trans_ihold(). 799 * Since the inode will be locked in all transactions, we must log 800 * the inode in every transaction to let it float upward through 801 * the log. 802 */ 803 trans = xfs_trans_alloc(mp, XFS_TRANS_ATTRINVAL); 804 if ((error = xfs_trans_reserve(trans, 0, XFS_ATTRINVAL_LOG_RES(mp), 0, 805 XFS_TRANS_PERM_LOG_RES, 806 XFS_ATTRINVAL_LOG_COUNT))) { 807 xfs_trans_cancel(trans, 0); 808 return(error); 809 } 810 xfs_ilock(dp, XFS_ILOCK_EXCL); 811 812 /* 813 * No need to make quota reservations here. We expect to release some 814 * blocks, not allocate, in the common case. 815 */ 816 xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL); 817 xfs_trans_ihold(trans, dp); 818 819 /* 820 * Decide on what work routines to call based on the inode size. 821 */ 822 if (!xfs_inode_hasattr(dp) || 823 dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { 824 error = 0; 825 goto out; 826 } 827 error = xfs_attr_root_inactive(&trans, dp); 828 if (error) 829 goto out; 830 /* 831 * signal synchronous inactive transactions unless this 832 * is a synchronous mount filesystem in which case we 833 * know that we're here because we've been called out of 834 * xfs_inactive which means that the last reference is gone 835 * and the unlink transaction has already hit the disk so 836 * async inactive transactions are safe. 837 */ 838 if ((error = xfs_itruncate_finish(&trans, dp, 0LL, XFS_ATTR_FORK, 839 (!(mp->m_flags & XFS_MOUNT_WSYNC) 840 ? 1 : 0)))) 841 goto out; 842 843 /* 844 * Commit the last in the sequence of transactions. 845 */ 846 xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE); 847 error = xfs_trans_commit(trans, XFS_TRANS_RELEASE_LOG_RES); 848 xfs_iunlock(dp, XFS_ILOCK_EXCL); 849 850 return(error); 851 852out: 853 xfs_trans_cancel(trans, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); 854 xfs_iunlock(dp, XFS_ILOCK_EXCL); 855 return(error); 856} 857 858 859 860/*======================================================================== 861 * External routines when attribute list is inside the inode 862 *========================================================================*/ 863 864/* 865 * Add a name to the shortform attribute list structure 866 * This is the external routine. 867 */ 868STATIC int 869xfs_attr_shortform_addname(xfs_da_args_t *args) 870{ 871 int newsize, forkoff, retval; 872 873 retval = xfs_attr_shortform_lookup(args); 874 if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) { 875 return(retval); 876 } else if (retval == EEXIST) { 877 if (args->flags & ATTR_CREATE) 878 return(retval); 879 retval = xfs_attr_shortform_remove(args); 880 ASSERT(retval == 0); 881 } 882 883 if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX || 884 args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX) 885 return(XFS_ERROR(ENOSPC)); 886 887 newsize = XFS_ATTR_SF_TOTSIZE(args->dp); 888 newsize += XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen); 889 890 forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize); 891 if (!forkoff) 892 return(XFS_ERROR(ENOSPC)); 893 894 xfs_attr_shortform_add(args, forkoff); 895 return(0); 896} 897 898 899/*======================================================================== 900 * External routines when attribute list is one block 901 *========================================================================*/ 902 903/* 904 * Add a name to the leaf attribute list structure 905 * 906 * This leaf block cannot have a "remote" value, we only call this routine 907 * if bmap_one_block() says there is only one block (ie: no remote blks). 908 */ 909STATIC int 910xfs_attr_leaf_addname(xfs_da_args_t *args) 911{ 912 xfs_inode_t *dp; 913 xfs_dabuf_t *bp; 914 int retval, error, committed, forkoff; 915 916 /* 917 * Read the (only) block in the attribute list in. 918 */ 919 dp = args->dp; 920 args->blkno = 0; 921 error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, 922 XFS_ATTR_FORK); 923 if (error) 924 return(error); 925 ASSERT(bp != NULL); 926 927 /* 928 * Look up the given attribute in the leaf block. Figure out if 929 * the given flags produce an error or call for an atomic rename. 930 */ 931 retval = xfs_attr_leaf_lookup_int(bp, args); 932 if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) { 933 xfs_da_brelse(args->trans, bp); 934 return(retval); 935 } else if (retval == EEXIST) { 936 if (args->flags & ATTR_CREATE) { /* pure create op */ 937 xfs_da_brelse(args->trans, bp); 938 return(retval); 939 } 940 args->op_flags |= XFS_DA_OP_RENAME; /* an atomic rename */ 941 args->blkno2 = args->blkno; /* set 2nd entry info*/ 942 args->index2 = args->index; 943 args->rmtblkno2 = args->rmtblkno; 944 args->rmtblkcnt2 = args->rmtblkcnt; 945 } 946 947 /* 948 * Add the attribute to the leaf block, transitioning to a Btree 949 * if required. 950 */ 951 retval = xfs_attr_leaf_add(bp, args); 952 xfs_da_buf_done(bp); 953 if (retval == ENOSPC) { 954 /* 955 * Promote the attribute list to the Btree format, then 956 * Commit that transaction so that the node_addname() call 957 * can manage its own transactions. 958 */ 959 xfs_bmap_init(args->flist, args->firstblock); 960 error = xfs_attr_leaf_to_node(args); 961 if (!error) { 962 error = xfs_bmap_finish(&args->trans, args->flist, 963 &committed); 964 } 965 if (error) { 966 ASSERT(committed); 967 args->trans = NULL; 968 xfs_bmap_cancel(args->flist); 969 return(error); 970 } 971 972 /* 973 * bmap_finish() may have committed the last trans and started 974 * a new one. We need the inode to be in all transactions. 975 */ 976 if (committed) { 977 xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); 978 xfs_trans_ihold(args->trans, dp); 979 } 980 981 /* 982 * Commit the current trans (including the inode) and start 983 * a new one. 984 */ 985 error = xfs_trans_roll(&args->trans, dp); 986 if (error) 987 return (error); 988 989 /* 990 * Fob the whole rest of the problem off on the Btree code. 991 */ 992 error = xfs_attr_node_addname(args); 993 return(error); 994 } 995 996 /* 997 * Commit the transaction that added the attr name so that 998 * later routines can manage their own transactions. 999 */ 1000 error = xfs_trans_roll(&args->trans, dp); 1001 if (error) 1002 return (error); 1003 1004 /* 1005 * If there was an out-of-line value, allocate the blocks we 1006 * identified for its storage and copy the value. This is done 1007 * after we create the attribute so that we don't overflow the 1008 * maximum size of a transaction and/or hit a deadlock. 1009 */ 1010 if (args->rmtblkno > 0) { 1011 error = xfs_attr_rmtval_set(args); 1012 if (error) 1013 return(error); 1014 } 1015 1016 /* 1017 * If this is an atomic rename operation, we must "flip" the 1018 * incomplete flags on the "new" and "old" attribute/value pairs 1019 * so that one disappears and one appears atomically. Then we 1020 * must remove the "old" attribute/value pair. 1021 */ 1022 if (args->op_flags & XFS_DA_OP_RENAME) { 1023 /* 1024 * In a separate transaction, set the incomplete flag on the 1025 * "old" attr and clear the incomplete flag on the "new" attr. 1026 */ 1027 error = xfs_attr_leaf_flipflags(args); 1028 if (error) 1029 return(error); 1030 1031 /* 1032 * Dismantle the "old" attribute/value pair by removing 1033 * a "remote" value (if it exists). 1034 */ 1035 args->index = args->index2; 1036 args->blkno = args->blkno2; 1037 args->rmtblkno = args->rmtblkno2; 1038 args->rmtblkcnt = args->rmtblkcnt2; 1039 if (args->rmtblkno) { 1040 error = xfs_attr_rmtval_remove(args); 1041 if (error) 1042 return(error); 1043 } 1044 1045 /* 1046 * Read in the block containing the "old" attr, then 1047 * remove the "old" attr from that block (neat, huh!) 1048 */ 1049 error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, 1050 &bp, XFS_ATTR_FORK); 1051 if (error) 1052 return(error); 1053 ASSERT(bp != NULL); 1054 (void)xfs_attr_leaf_remove(bp, args); 1055 1056 /* 1057 * If the result is small enough, shrink it all into the inode. 1058 */ 1059 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { 1060 xfs_bmap_init(args->flist, args->firstblock); 1061 error = xfs_attr_leaf_to_shortform(bp, args, forkoff); 1062 /* bp is gone due to xfs_da_shrink_inode */ 1063 if (!error) { 1064 error = xfs_bmap_finish(&args->trans, 1065 args->flist, 1066 &committed); 1067 } 1068 if (error) { 1069 ASSERT(committed); 1070 args->trans = NULL; 1071 xfs_bmap_cancel(args->flist); 1072 return(error); 1073 } 1074 1075 /* 1076 * bmap_finish() may have committed the last trans 1077 * and started a new one. We need the inode to be 1078 * in all transactions. 1079 */ 1080 if (committed) { 1081 xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); 1082 xfs_trans_ihold(args->trans, dp); 1083 } 1084 } else 1085 xfs_da_buf_done(bp); 1086 1087 /* 1088 * Commit the remove and start the next trans in series. 1089 */ 1090 error = xfs_trans_roll(&args->trans, dp); 1091 1092 } else if (args->rmtblkno > 0) { 1093 /* 1094 * Added a "remote" value, just clear the incomplete flag. 1095 */ 1096 error = xfs_attr_leaf_clearflag(args); 1097 } 1098 return(error); 1099} 1100 1101/* 1102 * Remove a name from the leaf attribute list structure 1103 * 1104 * This leaf block cannot have a "remote" value, we only call this routine 1105 * if bmap_one_block() says there is only one block (ie: no remote blks). 1106 */ 1107STATIC int 1108xfs_attr_leaf_removename(xfs_da_args_t *args) 1109{ 1110 xfs_inode_t *dp; 1111 xfs_dabuf_t *bp; 1112 int error, committed, forkoff; 1113 1114 /* 1115 * Remove the attribute. 1116 */ 1117 dp = args->dp; 1118 args->blkno = 0; 1119 error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, 1120 XFS_ATTR_FORK); 1121 if (error) { 1122 return(error); 1123 } 1124 1125 ASSERT(bp != NULL); 1126 error = xfs_attr_leaf_lookup_int(bp, args); 1127 if (error == ENOATTR) { 1128 xfs_da_brelse(args->trans, bp); 1129 return(error); 1130 } 1131 1132 (void)xfs_attr_leaf_remove(bp, args); 1133 1134 /* 1135 * If the result is small enough, shrink it all into the inode. 1136 */ 1137 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { 1138 xfs_bmap_init(args->flist, args->firstblock); 1139 error = xfs_attr_leaf_to_shortform(bp, args, forkoff); 1140 /* bp is gone due to xfs_da_shrink_inode */ 1141 if (!error) { 1142 error = xfs_bmap_finish(&args->trans, args->flist, 1143 &committed); 1144 } 1145 if (error) { 1146 ASSERT(committed); 1147 args->trans = NULL; 1148 xfs_bmap_cancel(args->flist); 1149 return(error); 1150 } 1151 1152 /* 1153 * bmap_finish() may have committed the last trans and started 1154 * a new one. We need the inode to be in all transactions. 1155 */ 1156 if (committed) { 1157 xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); 1158 xfs_trans_ihold(args->trans, dp); 1159 } 1160 } else 1161 xfs_da_buf_done(bp); 1162 return(0); 1163} 1164 1165/* 1166 * Look up a name in a leaf attribute list structure. 1167 * 1168 * This leaf block cannot have a "remote" value, we only call this routine 1169 * if bmap_one_block() says there is only one block (ie: no remote blks). 1170 */ 1171STATIC int 1172xfs_attr_leaf_get(xfs_da_args_t *args) 1173{ 1174 xfs_dabuf_t *bp; 1175 int error; 1176 1177 args->blkno = 0; 1178 error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, 1179 XFS_ATTR_FORK); 1180 if (error) 1181 return(error); 1182 ASSERT(bp != NULL); 1183 1184 error = xfs_attr_leaf_lookup_int(bp, args); 1185 if (error != EEXIST) { 1186 xfs_da_brelse(args->trans, bp); 1187 return(error); 1188 } 1189 error = xfs_attr_leaf_getvalue(bp, args); 1190 xfs_da_brelse(args->trans, bp); 1191 if (!error && (args->rmtblkno > 0) && !(args->flags & ATTR_KERNOVAL)) { 1192 error = xfs_attr_rmtval_get(args); 1193 } 1194 return(error); 1195} 1196 1197/* 1198 * Copy out attribute entries for attr_list(), for leaf attribute lists. 1199 */ 1200STATIC int 1201xfs_attr_leaf_list(xfs_attr_list_context_t *context) 1202{ 1203 xfs_attr_leafblock_t *leaf; 1204 int error; 1205 xfs_dabuf_t *bp; 1206 1207 context->cursor->blkno = 0; 1208 error = xfs_da_read_buf(NULL, context->dp, 0, -1, &bp, XFS_ATTR_FORK); 1209 if (error) 1210 return XFS_ERROR(error); 1211 ASSERT(bp != NULL); 1212 leaf = bp->data; 1213 if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC)) { 1214 XFS_CORRUPTION_ERROR("xfs_attr_leaf_list", XFS_ERRLEVEL_LOW, 1215 context->dp->i_mount, leaf); 1216 xfs_da_brelse(NULL, bp); 1217 return XFS_ERROR(EFSCORRUPTED); 1218 } 1219 1220 error = xfs_attr_leaf_list_int(bp, context); 1221 xfs_da_brelse(NULL, bp); 1222 return XFS_ERROR(error); 1223} 1224 1225 1226/*======================================================================== 1227 * External routines when attribute list size > XFS_LBSIZE(mp). 1228 *========================================================================*/ 1229 1230/* 1231 * Add a name to a Btree-format attribute list. 1232 * 1233 * This will involve walking down the Btree, and may involve splitting 1234 * leaf nodes and even splitting intermediate nodes up to and including 1235 * the root node (a special case of an intermediate node). 1236 * 1237 * "Remote" attribute values confuse the issue and atomic rename operations 1238 * add a whole extra layer of confusion on top of that. 1239 */ 1240STATIC int 1241xfs_attr_node_addname(xfs_da_args_t *args) 1242{ 1243 xfs_da_state_t *state; 1244 xfs_da_state_blk_t *blk; 1245 xfs_inode_t *dp; 1246 xfs_mount_t *mp; 1247 int committed, retval, error; 1248 1249 /* 1250 * Fill in bucket of arguments/results/context to carry around. 1251 */ 1252 dp = args->dp; 1253 mp = dp->i_mount; 1254restart: 1255 state = xfs_da_state_alloc(); 1256 state->args = args; 1257 state->mp = mp; 1258 state->blocksize = state->mp->m_sb.sb_blocksize; 1259 state->node_ents = state->mp->m_attr_node_ents; 1260 1261 /* 1262 * Search to see if name already exists, and get back a pointer 1263 * to where it should go. 1264 */ 1265 error = xfs_da_node_lookup_int(state, &retval); 1266 if (error) 1267 goto out; 1268 blk = &state->path.blk[ state->path.active-1 ]; 1269 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC); 1270 if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) { 1271 goto out; 1272 } else if (retval == EEXIST) { 1273 if (args->flags & ATTR_CREATE) 1274 goto out; 1275 args->op_flags |= XFS_DA_OP_RENAME; /* atomic rename op */ 1276 args->blkno2 = args->blkno; /* set 2nd entry info*/ 1277 args->index2 = args->index; 1278 args->rmtblkno2 = args->rmtblkno; 1279 args->rmtblkcnt2 = args->rmtblkcnt; 1280 args->rmtblkno = 0; 1281 args->rmtblkcnt = 0; 1282 } 1283 1284 retval = xfs_attr_leaf_add(blk->bp, state->args); 1285 if (retval == ENOSPC) { 1286 if (state->path.active == 1) { 1287 /* 1288 * Its really a single leaf node, but it had 1289 * out-of-line values so it looked like it *might* 1290 * have been a b-tree. 1291 */ 1292 xfs_da_state_free(state); 1293 xfs_bmap_init(args->flist, args->firstblock); 1294 error = xfs_attr_leaf_to_node(args); 1295 if (!error) { 1296 error = xfs_bmap_finish(&args->trans, 1297 args->flist, 1298 &committed); 1299 } 1300 if (error) { 1301 ASSERT(committed); 1302 args->trans = NULL; 1303 xfs_bmap_cancel(args->flist); 1304 goto out; 1305 } 1306 1307 /* 1308 * bmap_finish() may have committed the last trans 1309 * and started a new one. We need the inode to be 1310 * in all transactions. 1311 */ 1312 if (committed) { 1313 xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); 1314 xfs_trans_ihold(args->trans, dp); 1315 } 1316 1317 /* 1318 * Commit the node conversion and start the next 1319 * trans in the chain. 1320 */ 1321 error = xfs_trans_roll(&args->trans, dp); 1322 if (error) 1323 goto out; 1324 1325 goto restart; 1326 } 1327 1328 /* 1329 * Split as many Btree elements as required. 1330 * This code tracks the new and old attr's location 1331 * in the index/blkno/rmtblkno/rmtblkcnt fields and 1332 * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields. 1333 */ 1334 xfs_bmap_init(args->flist, args->firstblock); 1335 error = xfs_da_split(state); 1336 if (!error) { 1337 error = xfs_bmap_finish(&args->trans, args->flist, 1338 &committed); 1339 } 1340 if (error) { 1341 ASSERT(committed); 1342 args->trans = NULL; 1343 xfs_bmap_cancel(args->flist); 1344 goto out; 1345 } 1346 1347 /* 1348 * bmap_finish() may have committed the last trans and started 1349 * a new one. We need the inode to be in all transactions. 1350 */ 1351 if (committed) { 1352 xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); 1353 xfs_trans_ihold(args->trans, dp); 1354 } 1355 } else { 1356 /* 1357 * Addition succeeded, update Btree hashvals. 1358 */ 1359 xfs_da_fixhashpath(state, &state->path); 1360 } 1361 1362 /* 1363 * Kill the state structure, we're done with it and need to 1364 * allow the buffers to come back later. 1365 */ 1366 xfs_da_state_free(state); 1367 state = NULL; 1368 1369 /* 1370 * Commit the leaf addition or btree split and start the next 1371 * trans in the chain. 1372 */ 1373 error = xfs_trans_roll(&args->trans, dp); 1374 if (error) 1375 goto out; 1376 1377 /* 1378 * If there was an out-of-line value, allocate the blocks we 1379 * identified for its storage and copy the value. This is done 1380 * after we create the attribute so that we don't overflow the 1381 * maximum size of a transaction and/or hit a deadlock. 1382 */ 1383 if (args->rmtblkno > 0) { 1384 error = xfs_attr_rmtval_set(args); 1385 if (error) 1386 return(error); 1387 } 1388 1389 /* 1390 * If this is an atomic rename operation, we must "flip" the 1391 * incomplete flags on the "new" and "old" attribute/value pairs 1392 * so that one disappears and one appears atomically. Then we 1393 * must remove the "old" attribute/value pair. 1394 */ 1395 if (args->op_flags & XFS_DA_OP_RENAME) { 1396 /* 1397 * In a separate transaction, set the incomplete flag on the 1398 * "old" attr and clear the incomplete flag on the "new" attr. 1399 */ 1400 error = xfs_attr_leaf_flipflags(args); 1401 if (error) 1402 goto out; 1403 1404 /* 1405 * Dismantle the "old" attribute/value pair by removing 1406 * a "remote" value (if it exists). 1407 */ 1408 args->index = args->index2; 1409 args->blkno = args->blkno2; 1410 args->rmtblkno = args->rmtblkno2; 1411 args->rmtblkcnt = args->rmtblkcnt2; 1412 if (args->rmtblkno) { 1413 error = xfs_attr_rmtval_remove(args); 1414 if (error) 1415 return(error); 1416 } 1417 1418 /* 1419 * Re-find the "old" attribute entry after any split ops. 1420 * The INCOMPLETE flag means that we will find the "old" 1421 * attr, not the "new" one. 1422 */ 1423 args->flags |= XFS_ATTR_INCOMPLETE; 1424 state = xfs_da_state_alloc(); 1425 state->args = args; 1426 state->mp = mp; 1427 state->blocksize = state->mp->m_sb.sb_blocksize; 1428 state->node_ents = state->mp->m_attr_node_ents; 1429 state->inleaf = 0; 1430 error = xfs_da_node_lookup_int(state, &retval); 1431 if (error) 1432 goto out; 1433 1434 /* 1435 * Remove the name and update the hashvals in the tree. 1436 */ 1437 blk = &state->path.blk[ state->path.active-1 ]; 1438 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC); 1439 error = xfs_attr_leaf_remove(blk->bp, args); 1440 xfs_da_fixhashpath(state, &state->path); 1441 1442 /* 1443 * Check to see if the tree needs to be collapsed. 1444 */ 1445 if (retval && (state->path.active > 1)) { 1446 xfs_bmap_init(args->flist, args->firstblock); 1447 error = xfs_da_join(state); 1448 if (!error) { 1449 error = xfs_bmap_finish(&args->trans, 1450 args->flist, 1451 &committed); 1452 } 1453 if (error) { 1454 ASSERT(committed); 1455 args->trans = NULL; 1456 xfs_bmap_cancel(args->flist); 1457 goto out; 1458 } 1459 1460 /* 1461 * bmap_finish() may have committed the last trans 1462 * and started a new one. We need the inode to be 1463 * in all transactions. 1464 */ 1465 if (committed) { 1466 xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); 1467 xfs_trans_ihold(args->trans, dp); 1468 } 1469 } 1470 1471 /* 1472 * Commit and start the next trans in the chain. 1473 */ 1474 error = xfs_trans_roll(&args->trans, dp); 1475 if (error) 1476 goto out; 1477 1478 } else if (args->rmtblkno > 0) { 1479 /* 1480 * Added a "remote" value, just clear the incomplete flag. 1481 */ 1482 error = xfs_attr_leaf_clearflag(args); 1483 if (error) 1484 goto out; 1485 } 1486 retval = error = 0; 1487 1488out: 1489 if (state) 1490 xfs_da_state_free(state); 1491 if (error) 1492 return(error); 1493 return(retval); 1494} 1495 1496/* 1497 * Remove a name from a B-tree attribute list. 1498 * 1499 * This will involve walking down the Btree, and may involve joining 1500 * leaf nodes and even joining intermediate nodes up to and including 1501 * the root node (a special case of an intermediate node). 1502 */ 1503STATIC int 1504xfs_attr_node_removename(xfs_da_args_t *args) 1505{ 1506 xfs_da_state_t *state; 1507 xfs_da_state_blk_t *blk; 1508 xfs_inode_t *dp; 1509 xfs_dabuf_t *bp; 1510 int retval, error, committed, forkoff; 1511 1512 /* 1513 * Tie a string around our finger to remind us where we are. 1514 */ 1515 dp = args->dp; 1516 state = xfs_da_state_alloc(); 1517 state->args = args; 1518 state->mp = dp->i_mount; 1519 state->blocksize = state->mp->m_sb.sb_blocksize; 1520 state->node_ents = state->mp->m_attr_node_ents; 1521 1522 /* 1523 * Search to see if name exists, and get back a pointer to it. 1524 */ 1525 error = xfs_da_node_lookup_int(state, &retval); 1526 if (error || (retval != EEXIST)) { 1527 if (error == 0) 1528 error = retval; 1529 goto out; 1530 } 1531 1532 /* 1533 * If there is an out-of-line value, de-allocate the blocks. 1534 * This is done before we remove the attribute so that we don't 1535 * overflow the maximum size of a transaction and/or hit a deadlock. 1536 */ 1537 blk = &state->path.blk[ state->path.active-1 ]; 1538 ASSERT(blk->bp != NULL); 1539 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC); 1540 if (args->rmtblkno > 0) { 1541 /* 1542 * Fill in disk block numbers in the state structure 1543 * so that we can get the buffers back after we commit 1544 * several transactions in the following calls. 1545 */ 1546 error = xfs_attr_fillstate(state); 1547 if (error) 1548 goto out; 1549 1550 /* 1551 * Mark the attribute as INCOMPLETE, then bunmapi() the 1552 * remote value. 1553 */ 1554 error = xfs_attr_leaf_setflag(args); 1555 if (error) 1556 goto out; 1557 error = xfs_attr_rmtval_remove(args); 1558 if (error) 1559 goto out; 1560 1561 /* 1562 * Refill the state structure with buffers, the prior calls 1563 * released our buffers. 1564 */ 1565 error = xfs_attr_refillstate(state); 1566 if (error) 1567 goto out; 1568 } 1569 1570 /* 1571 * Remove the name and update the hashvals in the tree. 1572 */ 1573 blk = &state->path.blk[ state->path.active-1 ]; 1574 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC); 1575 retval = xfs_attr_leaf_remove(blk->bp, args); 1576 xfs_da_fixhashpath(state, &state->path); 1577 1578 /* 1579 * Check to see if the tree needs to be collapsed. 1580 */ 1581 if (retval && (state->path.active > 1)) { 1582 xfs_bmap_init(args->flist, args->firstblock); 1583 error = xfs_da_join(state); 1584 if (!error) { 1585 error = xfs_bmap_finish(&args->trans, args->flist, 1586 &committed); 1587 } 1588 if (error) { 1589 ASSERT(committed); 1590 args->trans = NULL; 1591 xfs_bmap_cancel(args->flist); 1592 goto out; 1593 } 1594 1595 /* 1596 * bmap_finish() may have committed the last trans and started 1597 * a new one. We need the inode to be in all transactions. 1598 */ 1599 if (committed) { 1600 xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); 1601 xfs_trans_ihold(args->trans, dp); 1602 } 1603 1604 /* 1605 * Commit the Btree join operation and start a new trans. 1606 */ 1607 error = xfs_trans_roll(&args->trans, dp); 1608 if (error) 1609 goto out; 1610 } 1611 1612 /* 1613 * If the result is small enough, push it all into the inode. 1614 */ 1615 if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { 1616 /* 1617 * Have to get rid of the copy of this dabuf in the state. 1618 */ 1619 ASSERT(state->path.active == 1); 1620 ASSERT(state->path.blk[0].bp); 1621 xfs_da_buf_done(state->path.blk[0].bp); 1622 state->path.blk[0].bp = NULL; 1623 1624 error = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, 1625 XFS_ATTR_FORK); 1626 if (error) 1627 goto out; 1628 ASSERT(be16_to_cpu(((xfs_attr_leafblock_t *) 1629 bp->data)->hdr.info.magic) 1630 == XFS_ATTR_LEAF_MAGIC); 1631 1632 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { 1633 xfs_bmap_init(args->flist, args->firstblock); 1634 error = xfs_attr_leaf_to_shortform(bp, args, forkoff); 1635 /* bp is gone due to xfs_da_shrink_inode */ 1636 if (!error) { 1637 error = xfs_bmap_finish(&args->trans, 1638 args->flist, 1639 &committed); 1640 } 1641 if (error) { 1642 ASSERT(committed); 1643 args->trans = NULL; 1644 xfs_bmap_cancel(args->flist); 1645 goto out; 1646 } 1647 1648 /* 1649 * bmap_finish() may have committed the last trans 1650 * and started a new one. We need the inode to be 1651 * in all transactions. 1652 */ 1653 if (committed) { 1654 xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); 1655 xfs_trans_ihold(args->trans, dp); 1656 } 1657 } else 1658 xfs_da_brelse(args->trans, bp); 1659 } 1660 error = 0; 1661 1662out: 1663 xfs_da_state_free(state); 1664 return(error); 1665} 1666 1667/* 1668 * Fill in the disk block numbers in the state structure for the buffers 1669 * that are attached to the state structure. 1670 * This is done so that we can quickly reattach ourselves to those buffers 1671 * after some set of transaction commits have released these buffers. 1672 */ 1673STATIC int 1674xfs_attr_fillstate(xfs_da_state_t *state) 1675{ 1676 xfs_da_state_path_t *path; 1677 xfs_da_state_blk_t *blk; 1678 int level; 1679 1680 /* 1681 * Roll down the "path" in the state structure, storing the on-disk 1682 * block number for those buffers in the "path". 1683 */ 1684 path = &state->path; 1685 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); 1686 for (blk = path->blk, level = 0; level < path->active; blk++, level++) { 1687 if (blk->bp) { 1688 blk->disk_blkno = xfs_da_blkno(blk->bp); 1689 xfs_da_buf_done(blk->bp); 1690 blk->bp = NULL; 1691 } else { 1692 blk->disk_blkno = 0; 1693 } 1694 } 1695 1696 /* 1697 * Roll down the "altpath" in the state structure, storing the on-disk 1698 * block number for those buffers in the "altpath". 1699 */ 1700 path = &state->altpath; 1701 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); 1702 for (blk = path->blk, level = 0; level < path->active; blk++, level++) { 1703 if (blk->bp) { 1704 blk->disk_blkno = xfs_da_blkno(blk->bp); 1705 xfs_da_buf_done(blk->bp); 1706 blk->bp = NULL; 1707 } else { 1708 blk->disk_blkno = 0; 1709 } 1710 } 1711 1712 return(0); 1713} 1714 1715/* 1716 * Reattach the buffers to the state structure based on the disk block 1717 * numbers stored in the state structure. 1718 * This is done after some set of transaction commits have released those 1719 * buffers from our grip. 1720 */ 1721STATIC int 1722xfs_attr_refillstate(xfs_da_state_t *state) 1723{ 1724 xfs_da_state_path_t *path; 1725 xfs_da_state_blk_t *blk; 1726 int level, error; 1727 1728 /* 1729 * Roll down the "path" in the state structure, storing the on-disk 1730 * block number for those buffers in the "path". 1731 */ 1732 path = &state->path; 1733 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); 1734 for (blk = path->blk, level = 0; level < path->active; blk++, level++) { 1735 if (blk->disk_blkno) { 1736 error = xfs_da_read_buf(state->args->trans, 1737 state->args->dp, 1738 blk->blkno, blk->disk_blkno, 1739 &blk->bp, XFS_ATTR_FORK); 1740 if (error) 1741 return(error); 1742 } else { 1743 blk->bp = NULL; 1744 } 1745 } 1746 1747 /* 1748 * Roll down the "altpath" in the state structure, storing the on-disk 1749 * block number for those buffers in the "altpath". 1750 */ 1751 path = &state->altpath; 1752 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); 1753 for (blk = path->blk, level = 0; level < path->active; blk++, level++) { 1754 if (blk->disk_blkno) { 1755 error = xfs_da_read_buf(state->args->trans, 1756 state->args->dp, 1757 blk->blkno, blk->disk_blkno, 1758 &blk->bp, XFS_ATTR_FORK); 1759 if (error) 1760 return(error); 1761 } else { 1762 blk->bp = NULL; 1763 } 1764 } 1765 1766 return(0); 1767} 1768 1769/* 1770 * Look up a filename in a node attribute list. 1771 * 1772 * This routine gets called for any attribute fork that has more than one 1773 * block, ie: both true Btree attr lists and for single-leaf-blocks with 1774 * "remote" values taking up more blocks. 1775 */ 1776STATIC int 1777xfs_attr_node_get(xfs_da_args_t *args) 1778{ 1779 xfs_da_state_t *state; 1780 xfs_da_state_blk_t *blk; 1781 int error, retval; 1782 int i; 1783 1784 state = xfs_da_state_alloc(); 1785 state->args = args; 1786 state->mp = args->dp->i_mount; 1787 state->blocksize = state->mp->m_sb.sb_blocksize; 1788 state->node_ents = state->mp->m_attr_node_ents; 1789 1790 /* 1791 * Search to see if name exists, and get back a pointer to it. 1792 */ 1793 error = xfs_da_node_lookup_int(state, &retval); 1794 if (error) { 1795 retval = error; 1796 } else if (retval == EEXIST) { 1797 blk = &state->path.blk[ state->path.active-1 ]; 1798 ASSERT(blk->bp != NULL); 1799 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC); 1800 1801 /* 1802 * Get the value, local or "remote" 1803 */ 1804 retval = xfs_attr_leaf_getvalue(blk->bp, args); 1805 if (!retval && (args->rmtblkno > 0) 1806 && !(args->flags & ATTR_KERNOVAL)) { 1807 retval = xfs_attr_rmtval_get(args); 1808 } 1809 } 1810 1811 /* 1812 * If not in a transaction, we have to release all the buffers. 1813 */ 1814 for (i = 0; i < state->path.active; i++) { 1815 xfs_da_brelse(args->trans, state->path.blk[i].bp); 1816 state->path.blk[i].bp = NULL; 1817 } 1818 1819 xfs_da_state_free(state); 1820 return(retval); 1821} 1822 1823STATIC int /* error */ 1824xfs_attr_node_list(xfs_attr_list_context_t *context) 1825{ 1826 attrlist_cursor_kern_t *cursor; 1827 xfs_attr_leafblock_t *leaf; 1828 xfs_da_intnode_t *node; 1829 xfs_da_node_entry_t *btree; 1830 int error, i; 1831 xfs_dabuf_t *bp; 1832 1833 cursor = context->cursor; 1834 cursor->initted = 1; 1835 1836 /* 1837 * Do all sorts of validation on the passed-in cursor structure. 1838 * If anything is amiss, ignore the cursor and look up the hashval 1839 * starting from the btree root. 1840 */ 1841 bp = NULL; 1842 if (cursor->blkno > 0) { 1843 error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1, 1844 &bp, XFS_ATTR_FORK); 1845 if ((error != 0) && (error != EFSCORRUPTED)) 1846 return(error); 1847 if (bp) { 1848 node = bp->data; 1849 switch (be16_to_cpu(node->hdr.info.magic)) { 1850 case XFS_DA_NODE_MAGIC: 1851 trace_xfs_attr_list_wrong_blk(context); 1852 xfs_da_brelse(NULL, bp); 1853 bp = NULL; 1854 break; 1855 case XFS_ATTR_LEAF_MAGIC: 1856 leaf = bp->data; 1857 if (cursor->hashval > be32_to_cpu(leaf->entries[ 1858 be16_to_cpu(leaf->hdr.count)-1].hashval)) { 1859 trace_xfs_attr_list_wrong_blk(context); 1860 xfs_da_brelse(NULL, bp); 1861 bp = NULL; 1862 } else if (cursor->hashval <= 1863 be32_to_cpu(leaf->entries[0].hashval)) { 1864 trace_xfs_attr_list_wrong_blk(context); 1865 xfs_da_brelse(NULL, bp); 1866 bp = NULL; 1867 } 1868 break; 1869 default: 1870 trace_xfs_attr_list_wrong_blk(context); 1871 xfs_da_brelse(NULL, bp); 1872 bp = NULL; 1873 } 1874 } 1875 } 1876 1877 /* 1878 * We did not find what we expected given the cursor's contents, 1879 * so we start from the top and work down based on the hash value. 1880 * Note that start of node block is same as start of leaf block. 1881 */ 1882 if (bp == NULL) { 1883 cursor->blkno = 0; 1884 for (;;) { 1885 error = xfs_da_read_buf(NULL, context->dp, 1886 cursor->blkno, -1, &bp, 1887 XFS_ATTR_FORK); 1888 if (error) 1889 return(error); 1890 if (unlikely(bp == NULL)) { 1891 XFS_ERROR_REPORT("xfs_attr_node_list(2)", 1892 XFS_ERRLEVEL_LOW, 1893 context->dp->i_mount); 1894 return(XFS_ERROR(EFSCORRUPTED)); 1895 } 1896 node = bp->data; 1897 if (be16_to_cpu(node->hdr.info.magic) 1898 == XFS_ATTR_LEAF_MAGIC) 1899 break; 1900 if (unlikely(be16_to_cpu(node->hdr.info.magic) 1901 != XFS_DA_NODE_MAGIC)) { 1902 XFS_CORRUPTION_ERROR("xfs_attr_node_list(3)", 1903 XFS_ERRLEVEL_LOW, 1904 context->dp->i_mount, 1905 node); 1906 xfs_da_brelse(NULL, bp); 1907 return(XFS_ERROR(EFSCORRUPTED)); 1908 } 1909 btree = node->btree; 1910 for (i = 0; i < be16_to_cpu(node->hdr.count); 1911 btree++, i++) { 1912 if (cursor->hashval 1913 <= be32_to_cpu(btree->hashval)) { 1914 cursor->blkno = be32_to_cpu(btree->before); 1915 trace_xfs_attr_list_node_descend(context, 1916 btree); 1917 break; 1918 } 1919 } 1920 if (i == be16_to_cpu(node->hdr.count)) { 1921 xfs_da_brelse(NULL, bp); 1922 return(0); 1923 } 1924 xfs_da_brelse(NULL, bp); 1925 } 1926 } 1927 ASSERT(bp != NULL); 1928 1929 /* 1930 * Roll upward through the blocks, processing each leaf block in 1931 * order. As long as there is space in the result buffer, keep 1932 * adding the information. 1933 */ 1934 for (;;) { 1935 leaf = bp->data; 1936 if (unlikely(be16_to_cpu(leaf->hdr.info.magic) 1937 != XFS_ATTR_LEAF_MAGIC)) { 1938 XFS_CORRUPTION_ERROR("xfs_attr_node_list(4)", 1939 XFS_ERRLEVEL_LOW, 1940 context->dp->i_mount, leaf); 1941 xfs_da_brelse(NULL, bp); 1942 return(XFS_ERROR(EFSCORRUPTED)); 1943 } 1944 error = xfs_attr_leaf_list_int(bp, context); 1945 if (error) { 1946 xfs_da_brelse(NULL, bp); 1947 return error; 1948 } 1949 if (context->seen_enough || leaf->hdr.info.forw == 0) 1950 break; 1951 cursor->blkno = be32_to_cpu(leaf->hdr.info.forw); 1952 xfs_da_brelse(NULL, bp); 1953 error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1, 1954 &bp, XFS_ATTR_FORK); 1955 if (error) 1956 return(error); 1957 if (unlikely((bp == NULL))) { 1958 XFS_ERROR_REPORT("xfs_attr_node_list(5)", 1959 XFS_ERRLEVEL_LOW, 1960 context->dp->i_mount); 1961 return(XFS_ERROR(EFSCORRUPTED)); 1962 } 1963 } 1964 xfs_da_brelse(NULL, bp); 1965 return(0); 1966} 1967 1968 1969/*======================================================================== 1970 * External routines for manipulating out-of-line attribute values. 1971 *========================================================================*/ 1972 1973/* 1974 * Read the value associated with an attribute from the out-of-line buffer 1975 * that we stored it in. 1976 */ 1977int 1978xfs_attr_rmtval_get(xfs_da_args_t *args) 1979{ 1980 xfs_bmbt_irec_t map[ATTR_RMTVALUE_MAPSIZE]; 1981 xfs_mount_t *mp; 1982 xfs_daddr_t dblkno; 1983 xfs_caddr_t dst; 1984 xfs_buf_t *bp; 1985 int nmap, error, tmp, valuelen, blkcnt, i; 1986 xfs_dablk_t lblkno; 1987 1988 ASSERT(!(args->flags & ATTR_KERNOVAL)); 1989 1990 mp = args->dp->i_mount; 1991 dst = args->value; 1992 valuelen = args->valuelen; 1993 lblkno = args->rmtblkno; 1994 while (valuelen > 0) { 1995 nmap = ATTR_RMTVALUE_MAPSIZE; 1996 error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno, 1997 args->rmtblkcnt, 1998 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 1999 NULL, 0, map, &nmap, NULL, NULL); 2000 if (error) 2001 return(error); 2002 ASSERT(nmap >= 1); 2003 2004 for (i = 0; (i < nmap) && (valuelen > 0); i++) { 2005 ASSERT((map[i].br_startblock != DELAYSTARTBLOCK) && 2006 (map[i].br_startblock != HOLESTARTBLOCK)); 2007 dblkno = XFS_FSB_TO_DADDR(mp, map[i].br_startblock); 2008 blkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount); 2009 error = xfs_read_buf(mp, mp->m_ddev_targp, dblkno, 2010 blkcnt, 2011 XFS_BUF_LOCK | XBF_DONT_BLOCK, 2012 &bp); 2013 if (error) 2014 return(error); 2015 2016 tmp = (valuelen < XFS_BUF_SIZE(bp)) 2017 ? valuelen : XFS_BUF_SIZE(bp); 2018 xfs_biomove(bp, 0, tmp, dst, XFS_B_READ); 2019 xfs_buf_relse(bp); 2020 dst += tmp; 2021 valuelen -= tmp; 2022 2023 lblkno += map[i].br_blockcount; 2024 } 2025 } 2026 ASSERT(valuelen == 0); 2027 return(0); 2028} 2029 2030/* 2031 * Write the value associated with an attribute into the out-of-line buffer 2032 * that we have defined for it. 2033 */ 2034STATIC int 2035xfs_attr_rmtval_set(xfs_da_args_t *args) 2036{ 2037 xfs_mount_t *mp; 2038 xfs_fileoff_t lfileoff; 2039 xfs_inode_t *dp; 2040 xfs_bmbt_irec_t map; 2041 xfs_daddr_t dblkno; 2042 xfs_caddr_t src; 2043 xfs_buf_t *bp; 2044 xfs_dablk_t lblkno; 2045 int blkcnt, valuelen, nmap, error, tmp, committed; 2046 2047 dp = args->dp; 2048 mp = dp->i_mount; 2049 src = args->value; 2050 2051 /* 2052 * Find a "hole" in the attribute address space large enough for 2053 * us to drop the new attribute's value into. 2054 */ 2055 blkcnt = XFS_B_TO_FSB(mp, args->valuelen); 2056 lfileoff = 0; 2057 error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff, 2058 XFS_ATTR_FORK); 2059 if (error) { 2060 return(error); 2061 } 2062 args->rmtblkno = lblkno = (xfs_dablk_t)lfileoff; 2063 args->rmtblkcnt = blkcnt; 2064 2065 /* 2066 * Roll through the "value", allocating blocks on disk as required. 2067 */ 2068 while (blkcnt > 0) { 2069 /* 2070 * Allocate a single extent, up to the size of the value. 2071 */ 2072 xfs_bmap_init(args->flist, args->firstblock); 2073 nmap = 1; 2074 error = xfs_bmapi(args->trans, dp, (xfs_fileoff_t)lblkno, 2075 blkcnt, 2076 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA | 2077 XFS_BMAPI_WRITE, 2078 args->firstblock, args->total, &map, &nmap, 2079 args->flist, NULL); 2080 if (!error) { 2081 error = xfs_bmap_finish(&args->trans, args->flist, 2082 &committed); 2083 } 2084 if (error) { 2085 ASSERT(committed); 2086 args->trans = NULL; 2087 xfs_bmap_cancel(args->flist); 2088 return(error); 2089 } 2090 2091 /* 2092 * bmap_finish() may have committed the last trans and started 2093 * a new one. We need the inode to be in all transactions. 2094 */ 2095 if (committed) { 2096 xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); 2097 xfs_trans_ihold(args->trans, dp); 2098 } 2099 2100 ASSERT(nmap == 1); 2101 ASSERT((map.br_startblock != DELAYSTARTBLOCK) && 2102 (map.br_startblock != HOLESTARTBLOCK)); 2103 lblkno += map.br_blockcount; 2104 blkcnt -= map.br_blockcount; 2105 2106 /* 2107 * Start the next trans in the chain. 2108 */ 2109 error = xfs_trans_roll(&args->trans, dp); 2110 if (error) 2111 return (error); 2112 } 2113 2114 /* 2115 * Roll through the "value", copying the attribute value to the 2116 * already-allocated blocks. Blocks are written synchronously 2117 * so that we can know they are all on disk before we turn off 2118 * the INCOMPLETE flag. 2119 */ 2120 lblkno = args->rmtblkno; 2121 valuelen = args->valuelen; 2122 while (valuelen > 0) { 2123 /* 2124 * Try to remember where we decided to put the value. 2125 */ 2126 xfs_bmap_init(args->flist, args->firstblock); 2127 nmap = 1; 2128 error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno, 2129 args->rmtblkcnt, 2130 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2131 args->firstblock, 0, &map, &nmap, 2132 NULL, NULL); 2133 if (error) { 2134 return(error); 2135 } 2136 ASSERT(nmap == 1); 2137 ASSERT((map.br_startblock != DELAYSTARTBLOCK) && 2138 (map.br_startblock != HOLESTARTBLOCK)); 2139 2140 dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock), 2141 blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); 2142 2143 bp = xfs_buf_get(mp->m_ddev_targp, dblkno, blkcnt, 2144 XFS_BUF_LOCK | XBF_DONT_BLOCK); 2145 ASSERT(bp); 2146 ASSERT(!XFS_BUF_GETERROR(bp)); 2147 2148 tmp = (valuelen < XFS_BUF_SIZE(bp)) ? valuelen : 2149 XFS_BUF_SIZE(bp); 2150 xfs_biomove(bp, 0, tmp, src, XFS_B_WRITE); 2151 if (tmp < XFS_BUF_SIZE(bp)) 2152 xfs_biozero(bp, tmp, XFS_BUF_SIZE(bp) - tmp); 2153 if ((error = xfs_bwrite(mp, bp))) {/* GROT: NOTE: synchronous write */ 2154 return (error); 2155 } 2156 src += tmp; 2157 valuelen -= tmp; 2158 2159 lblkno += map.br_blockcount; 2160 } 2161 ASSERT(valuelen == 0); 2162 return(0); 2163} 2164 2165/* 2166 * Remove the value associated with an attribute by deleting the 2167 * out-of-line buffer that it is stored on. 2168 */ 2169STATIC int 2170xfs_attr_rmtval_remove(xfs_da_args_t *args) 2171{ 2172 xfs_mount_t *mp; 2173 xfs_bmbt_irec_t map; 2174 xfs_buf_t *bp; 2175 xfs_daddr_t dblkno; 2176 xfs_dablk_t lblkno; 2177 int valuelen, blkcnt, nmap, error, done, committed; 2178 2179 mp = args->dp->i_mount; 2180 2181 /* 2182 * Roll through the "value", invalidating the attribute value's 2183 * blocks. 2184 */ 2185 lblkno = args->rmtblkno; 2186 valuelen = args->rmtblkcnt; 2187 while (valuelen > 0) { 2188 /* 2189 * Try to remember where we decided to put the value. 2190 */ 2191 xfs_bmap_init(args->flist, args->firstblock); 2192 nmap = 1; 2193 error = xfs_bmapi(NULL, args->dp, (xfs_fileoff_t)lblkno, 2194 args->rmtblkcnt, 2195 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2196 args->firstblock, 0, &map, &nmap, 2197 args->flist, NULL); 2198 if (error) { 2199 return(error); 2200 } 2201 ASSERT(nmap == 1); 2202 ASSERT((map.br_startblock != DELAYSTARTBLOCK) && 2203 (map.br_startblock != HOLESTARTBLOCK)); 2204 2205 dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock), 2206 blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); 2207 2208 /* 2209 * If the "remote" value is in the cache, remove it. 2210 */ 2211 bp = xfs_incore(mp->m_ddev_targp, dblkno, blkcnt, 2212 XFS_INCORE_TRYLOCK); 2213 if (bp) { 2214 XFS_BUF_STALE(bp); 2215 XFS_BUF_UNDELAYWRITE(bp); 2216 xfs_buf_relse(bp); 2217 bp = NULL; 2218 } 2219 2220 valuelen -= map.br_blockcount; 2221 2222 lblkno += map.br_blockcount; 2223 } 2224 2225 /* 2226 * Keep de-allocating extents until the remote-value region is gone. 2227 */ 2228 lblkno = args->rmtblkno; 2229 blkcnt = args->rmtblkcnt; 2230 done = 0; 2231 while (!done) { 2232 xfs_bmap_init(args->flist, args->firstblock); 2233 error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, 2234 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2235 1, args->firstblock, args->flist, 2236 NULL, &done); 2237 if (!error) { 2238 error = xfs_bmap_finish(&args->trans, args->flist, 2239 &committed); 2240 } 2241 if (error) { 2242 ASSERT(committed); 2243 args->trans = NULL; 2244 xfs_bmap_cancel(args->flist); 2245 return(error); 2246 } 2247 2248 /* 2249 * bmap_finish() may have committed the last trans and started 2250 * a new one. We need the inode to be in all transactions. 2251 */ 2252 if (committed) { 2253 xfs_trans_ijoin(args->trans, args->dp, XFS_ILOCK_EXCL); 2254 xfs_trans_ihold(args->trans, args->dp); 2255 } 2256 2257 /* 2258 * Close out trans and start the next one in the chain. 2259 */ 2260 error = xfs_trans_roll(&args->trans, args->dp); 2261 if (error) 2262 return (error); 2263 } 2264 return(0); 2265}