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