| .. | .. |
|---|
| 10 | 10 | #include "xfs_format.h" |
|---|
| 11 | 11 | #include "xfs_log_format.h" |
|---|
| 12 | 12 | #include "xfs_trans_resv.h" |
|---|
| 13 | | -#include "xfs_bit.h" |
|---|
| 14 | 13 | #include "xfs_sb.h" |
|---|
| 15 | 14 | #include "xfs_mount.h" |
|---|
| 16 | 15 | #include "xfs_da_format.h" |
|---|
| 17 | 16 | #include "xfs_da_btree.h" |
|---|
| 18 | 17 | #include "xfs_inode.h" |
|---|
| 19 | 18 | #include "xfs_trans.h" |
|---|
| 20 | | -#include "xfs_inode_item.h" |
|---|
| 21 | 19 | #include "xfs_bmap_btree.h" |
|---|
| 22 | 20 | #include "xfs_bmap.h" |
|---|
| 23 | 21 | #include "xfs_attr_sf.h" |
|---|
| .. | .. |
|---|
| 27 | 25 | #include "xfs_error.h" |
|---|
| 28 | 26 | #include "xfs_trace.h" |
|---|
| 29 | 27 | #include "xfs_buf_item.h" |
|---|
| 30 | | -#include "xfs_cksum.h" |
|---|
| 31 | 28 | #include "xfs_dir2.h" |
|---|
| 32 | 29 | #include "xfs_log.h" |
|---|
| 33 | 30 | |
|---|
| .. | .. |
|---|
| 236 | 233 | } |
|---|
| 237 | 234 | |
|---|
| 238 | 235 | static xfs_failaddr_t |
|---|
| 236 | +xfs_attr3_leaf_verify_entry( |
|---|
| 237 | + struct xfs_mount *mp, |
|---|
| 238 | + char *buf_end, |
|---|
| 239 | + struct xfs_attr_leafblock *leaf, |
|---|
| 240 | + struct xfs_attr3_icleaf_hdr *leafhdr, |
|---|
| 241 | + struct xfs_attr_leaf_entry *ent, |
|---|
| 242 | + int idx, |
|---|
| 243 | + __u32 *last_hashval) |
|---|
| 244 | +{ |
|---|
| 245 | + struct xfs_attr_leaf_name_local *lentry; |
|---|
| 246 | + struct xfs_attr_leaf_name_remote *rentry; |
|---|
| 247 | + char *name_end; |
|---|
| 248 | + unsigned int nameidx; |
|---|
| 249 | + unsigned int namesize; |
|---|
| 250 | + __u32 hashval; |
|---|
| 251 | + |
|---|
| 252 | + /* hash order check */ |
|---|
| 253 | + hashval = be32_to_cpu(ent->hashval); |
|---|
| 254 | + if (hashval < *last_hashval) |
|---|
| 255 | + return __this_address; |
|---|
| 256 | + *last_hashval = hashval; |
|---|
| 257 | + |
|---|
| 258 | + nameidx = be16_to_cpu(ent->nameidx); |
|---|
| 259 | + if (nameidx < leafhdr->firstused || nameidx >= mp->m_attr_geo->blksize) |
|---|
| 260 | + return __this_address; |
|---|
| 261 | + |
|---|
| 262 | + /* |
|---|
| 263 | + * Check the name information. The namelen fields are u8 so we can't |
|---|
| 264 | + * possibly exceed the maximum name length of 255 bytes. |
|---|
| 265 | + */ |
|---|
| 266 | + if (ent->flags & XFS_ATTR_LOCAL) { |
|---|
| 267 | + lentry = xfs_attr3_leaf_name_local(leaf, idx); |
|---|
| 268 | + namesize = xfs_attr_leaf_entsize_local(lentry->namelen, |
|---|
| 269 | + be16_to_cpu(lentry->valuelen)); |
|---|
| 270 | + name_end = (char *)lentry + namesize; |
|---|
| 271 | + if (lentry->namelen == 0) |
|---|
| 272 | + return __this_address; |
|---|
| 273 | + } else { |
|---|
| 274 | + rentry = xfs_attr3_leaf_name_remote(leaf, idx); |
|---|
| 275 | + namesize = xfs_attr_leaf_entsize_remote(rentry->namelen); |
|---|
| 276 | + name_end = (char *)rentry + namesize; |
|---|
| 277 | + if (rentry->namelen == 0) |
|---|
| 278 | + return __this_address; |
|---|
| 279 | + if (!(ent->flags & XFS_ATTR_INCOMPLETE) && |
|---|
| 280 | + rentry->valueblk == 0) |
|---|
| 281 | + return __this_address; |
|---|
| 282 | + } |
|---|
| 283 | + |
|---|
| 284 | + if (name_end > buf_end) |
|---|
| 285 | + return __this_address; |
|---|
| 286 | + |
|---|
| 287 | + return NULL; |
|---|
| 288 | +} |
|---|
| 289 | + |
|---|
| 290 | +static xfs_failaddr_t |
|---|
| 239 | 291 | xfs_attr3_leaf_verify( |
|---|
| 240 | 292 | struct xfs_buf *bp) |
|---|
| 241 | 293 | { |
|---|
| 242 | 294 | struct xfs_attr3_icleaf_hdr ichdr; |
|---|
| 243 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 295 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 244 | 296 | struct xfs_attr_leafblock *leaf = bp->b_addr; |
|---|
| 245 | 297 | struct xfs_attr_leaf_entry *entries; |
|---|
| 298 | + struct xfs_attr_leaf_entry *ent; |
|---|
| 299 | + char *buf_end; |
|---|
| 246 | 300 | uint32_t end; /* must be 32bit - see below */ |
|---|
| 301 | + __u32 last_hashval = 0; |
|---|
| 247 | 302 | int i; |
|---|
| 303 | + xfs_failaddr_t fa; |
|---|
| 248 | 304 | |
|---|
| 249 | 305 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf); |
|---|
| 250 | 306 | |
|---|
| 251 | | - if (xfs_sb_version_hascrc(&mp->m_sb)) { |
|---|
| 252 | | - struct xfs_da3_node_hdr *hdr3 = bp->b_addr; |
|---|
| 253 | | - |
|---|
| 254 | | - if (ichdr.magic != XFS_ATTR3_LEAF_MAGIC) |
|---|
| 255 | | - return __this_address; |
|---|
| 256 | | - |
|---|
| 257 | | - if (!uuid_equal(&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid)) |
|---|
| 258 | | - return __this_address; |
|---|
| 259 | | - if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn) |
|---|
| 260 | | - return __this_address; |
|---|
| 261 | | - if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->info.lsn))) |
|---|
| 262 | | - return __this_address; |
|---|
| 263 | | - } else { |
|---|
| 264 | | - if (ichdr.magic != XFS_ATTR_LEAF_MAGIC) |
|---|
| 265 | | - return __this_address; |
|---|
| 266 | | - } |
|---|
| 267 | | - /* |
|---|
| 268 | | - * In recovery there is a transient state where count == 0 is valid |
|---|
| 269 | | - * because we may have transitioned an empty shortform attr to a leaf |
|---|
| 270 | | - * if the attr didn't fit in shortform. |
|---|
| 271 | | - */ |
|---|
| 272 | | - if (!xfs_log_in_recovery(mp) && ichdr.count == 0) |
|---|
| 273 | | - return __this_address; |
|---|
| 307 | + fa = xfs_da3_blkinfo_verify(bp, bp->b_addr); |
|---|
| 308 | + if (fa) |
|---|
| 309 | + return fa; |
|---|
| 274 | 310 | |
|---|
| 275 | 311 | /* |
|---|
| 276 | 312 | * firstused is the block offset of the first name info structure. |
|---|
| .. | .. |
|---|
| 287 | 323 | (char *)bp->b_addr + ichdr.firstused) |
|---|
| 288 | 324 | return __this_address; |
|---|
| 289 | 325 | |
|---|
| 290 | | - /* XXX: need to range check rest of attr header values */ |
|---|
| 291 | | - /* XXX: hash order check? */ |
|---|
| 326 | + /* |
|---|
| 327 | + * NOTE: This verifier historically failed empty leaf buffers because |
|---|
| 328 | + * we expect the fork to be in another format. Empty attr fork format |
|---|
| 329 | + * conversions are possible during xattr set, however, and format |
|---|
| 330 | + * conversion is not atomic with the xattr set that triggers it. We |
|---|
| 331 | + * cannot assume leaf blocks are non-empty until that is addressed. |
|---|
| 332 | + */ |
|---|
| 333 | + buf_end = (char *)bp->b_addr + mp->m_attr_geo->blksize; |
|---|
| 334 | + for (i = 0, ent = entries; i < ichdr.count; ent++, i++) { |
|---|
| 335 | + fa = xfs_attr3_leaf_verify_entry(mp, buf_end, leaf, &ichdr, |
|---|
| 336 | + ent, i, &last_hashval); |
|---|
| 337 | + if (fa) |
|---|
| 338 | + return fa; |
|---|
| 339 | + } |
|---|
| 292 | 340 | |
|---|
| 293 | 341 | /* |
|---|
| 294 | 342 | * Quickly check the freemap information. Attribute data has to be |
|---|
| .. | .. |
|---|
| 324 | 372 | xfs_attr3_leaf_write_verify( |
|---|
| 325 | 373 | struct xfs_buf *bp) |
|---|
| 326 | 374 | { |
|---|
| 327 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 375 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 328 | 376 | struct xfs_buf_log_item *bip = bp->b_log_item; |
|---|
| 329 | 377 | struct xfs_attr3_leaf_hdr *hdr3 = bp->b_addr; |
|---|
| 330 | 378 | xfs_failaddr_t fa; |
|---|
| .. | .. |
|---|
| 354 | 402 | xfs_attr3_leaf_read_verify( |
|---|
| 355 | 403 | struct xfs_buf *bp) |
|---|
| 356 | 404 | { |
|---|
| 357 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 405 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 358 | 406 | xfs_failaddr_t fa; |
|---|
| 359 | 407 | |
|---|
| 360 | 408 | if (xfs_sb_version_hascrc(&mp->m_sb) && |
|---|
| .. | .. |
|---|
| 369 | 417 | |
|---|
| 370 | 418 | const struct xfs_buf_ops xfs_attr3_leaf_buf_ops = { |
|---|
| 371 | 419 | .name = "xfs_attr3_leaf", |
|---|
| 420 | + .magic16 = { cpu_to_be16(XFS_ATTR_LEAF_MAGIC), |
|---|
| 421 | + cpu_to_be16(XFS_ATTR3_LEAF_MAGIC) }, |
|---|
| 372 | 422 | .verify_read = xfs_attr3_leaf_read_verify, |
|---|
| 373 | 423 | .verify_write = xfs_attr3_leaf_write_verify, |
|---|
| 374 | 424 | .verify_struct = xfs_attr3_leaf_verify, |
|---|
| .. | .. |
|---|
| 379 | 429 | struct xfs_trans *tp, |
|---|
| 380 | 430 | struct xfs_inode *dp, |
|---|
| 381 | 431 | xfs_dablk_t bno, |
|---|
| 382 | | - xfs_daddr_t mappedbno, |
|---|
| 383 | 432 | struct xfs_buf **bpp) |
|---|
| 384 | 433 | { |
|---|
| 385 | 434 | int err; |
|---|
| 386 | 435 | |
|---|
| 387 | | - err = xfs_da_read_buf(tp, dp, bno, mappedbno, bpp, |
|---|
| 388 | | - XFS_ATTR_FORK, &xfs_attr3_leaf_buf_ops); |
|---|
| 436 | + err = xfs_da_read_buf(tp, dp, bno, 0, bpp, XFS_ATTR_FORK, |
|---|
| 437 | + &xfs_attr3_leaf_buf_ops); |
|---|
| 389 | 438 | if (!err && tp && *bpp) |
|---|
| 390 | 439 | xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_ATTR_LEAF_BUF); |
|---|
| 391 | 440 | return err; |
|---|
| .. | .. |
|---|
| 395 | 444 | * Namespace helper routines |
|---|
| 396 | 445 | *========================================================================*/ |
|---|
| 397 | 446 | |
|---|
| 398 | | -/* |
|---|
| 399 | | - * If namespace bits don't match return 0. |
|---|
| 400 | | - * If all match then return 1. |
|---|
| 401 | | - */ |
|---|
| 402 | | -STATIC int |
|---|
| 403 | | -xfs_attr_namesp_match(int arg_flags, int ondisk_flags) |
|---|
| 447 | +static bool |
|---|
| 448 | +xfs_attr_match( |
|---|
| 449 | + struct xfs_da_args *args, |
|---|
| 450 | + uint8_t namelen, |
|---|
| 451 | + unsigned char *name, |
|---|
| 452 | + int flags) |
|---|
| 404 | 453 | { |
|---|
| 405 | | - return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags); |
|---|
| 454 | + if (args->namelen != namelen) |
|---|
| 455 | + return false; |
|---|
| 456 | + if (memcmp(args->name, name, namelen) != 0) |
|---|
| 457 | + return false; |
|---|
| 458 | + /* |
|---|
| 459 | + * If we are looking for incomplete entries, show only those, else only |
|---|
| 460 | + * show complete entries. |
|---|
| 461 | + */ |
|---|
| 462 | + if (args->attr_filter != |
|---|
| 463 | + (flags & (XFS_ATTR_NSP_ONDISK_MASK | XFS_ATTR_INCOMPLETE))) |
|---|
| 464 | + return false; |
|---|
| 465 | + return true; |
|---|
| 406 | 466 | } |
|---|
| 407 | 467 | |
|---|
| 468 | +static int |
|---|
| 469 | +xfs_attr_copy_value( |
|---|
| 470 | + struct xfs_da_args *args, |
|---|
| 471 | + unsigned char *value, |
|---|
| 472 | + int valuelen) |
|---|
| 473 | +{ |
|---|
| 474 | + /* |
|---|
| 475 | + * No copy if all we have to do is get the length |
|---|
| 476 | + */ |
|---|
| 477 | + if (!args->valuelen) { |
|---|
| 478 | + args->valuelen = valuelen; |
|---|
| 479 | + return 0; |
|---|
| 480 | + } |
|---|
| 481 | + |
|---|
| 482 | + /* |
|---|
| 483 | + * No copy if the length of the existing buffer is too small |
|---|
| 484 | + */ |
|---|
| 485 | + if (args->valuelen < valuelen) { |
|---|
| 486 | + args->valuelen = valuelen; |
|---|
| 487 | + return -ERANGE; |
|---|
| 488 | + } |
|---|
| 489 | + |
|---|
| 490 | + if (!args->value) { |
|---|
| 491 | + args->value = kmem_alloc_large(valuelen, KM_NOLOCKDEP); |
|---|
| 492 | + if (!args->value) |
|---|
| 493 | + return -ENOMEM; |
|---|
| 494 | + } |
|---|
| 495 | + args->valuelen = valuelen; |
|---|
| 496 | + |
|---|
| 497 | + /* remote block xattr requires IO for copy-in */ |
|---|
| 498 | + if (args->rmtblkno) |
|---|
| 499 | + return xfs_attr_rmtval_get(args); |
|---|
| 500 | + |
|---|
| 501 | + /* |
|---|
| 502 | + * This is to prevent a GCC warning because the remote xattr case |
|---|
| 503 | + * doesn't have a value to pass in. In that case, we never reach here, |
|---|
| 504 | + * but GCC can't work that out and so throws a "passing NULL to |
|---|
| 505 | + * memcpy" warning. |
|---|
| 506 | + */ |
|---|
| 507 | + if (!value) |
|---|
| 508 | + return -EINVAL; |
|---|
| 509 | + memcpy(args->value, value, valuelen); |
|---|
| 510 | + return 0; |
|---|
| 511 | +} |
|---|
| 408 | 512 | |
|---|
| 409 | 513 | /*======================================================================== |
|---|
| 410 | 514 | * External routines when attribute fork size < XFS_LITINO(mp). |
|---|
| 411 | 515 | *========================================================================*/ |
|---|
| 412 | 516 | |
|---|
| 413 | 517 | /* |
|---|
| 414 | | - * Query whether the requested number of additional bytes of extended |
|---|
| 518 | + * Query whether the total requested number of attr fork bytes of extended |
|---|
| 415 | 519 | * attribute space will be able to fit inline. |
|---|
| 416 | 520 | * |
|---|
| 417 | 521 | * Returns zero if not, else the di_forkoff fork offset to be used in the |
|---|
| .. | .. |
|---|
| 421 | 525 | * special case for dev/uuid inodes, they have fixed size data forks. |
|---|
| 422 | 526 | */ |
|---|
| 423 | 527 | int |
|---|
| 424 | | -xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes) |
|---|
| 528 | +xfs_attr_shortform_bytesfit( |
|---|
| 529 | + struct xfs_inode *dp, |
|---|
| 530 | + int bytes) |
|---|
| 425 | 531 | { |
|---|
| 426 | | - int offset; |
|---|
| 427 | | - int minforkoff; /* lower limit on valid forkoff locations */ |
|---|
| 428 | | - int maxforkoff; /* upper limit on valid forkoff locations */ |
|---|
| 429 | | - int dsize; |
|---|
| 430 | | - xfs_mount_t *mp = dp->i_mount; |
|---|
| 532 | + struct xfs_mount *mp = dp->i_mount; |
|---|
| 533 | + int64_t dsize; |
|---|
| 534 | + int minforkoff; |
|---|
| 535 | + int maxforkoff; |
|---|
| 536 | + int offset; |
|---|
| 537 | + |
|---|
| 538 | + /* |
|---|
| 539 | + * Check if the new size could fit at all first: |
|---|
| 540 | + */ |
|---|
| 541 | + if (bytes > XFS_LITINO(mp)) |
|---|
| 542 | + return 0; |
|---|
| 431 | 543 | |
|---|
| 432 | 544 | /* rounded down */ |
|---|
| 433 | | - offset = (XFS_LITINO(mp, dp->i_d.di_version) - bytes) >> 3; |
|---|
| 545 | + offset = (XFS_LITINO(mp) - bytes) >> 3; |
|---|
| 434 | 546 | |
|---|
| 435 | | - if (dp->i_d.di_format == XFS_DINODE_FMT_DEV) { |
|---|
| 547 | + if (dp->i_df.if_format == XFS_DINODE_FMT_DEV) { |
|---|
| 436 | 548 | minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; |
|---|
| 437 | 549 | return (offset >= minforkoff) ? minforkoff : 0; |
|---|
| 438 | 550 | } |
|---|
| .. | .. |
|---|
| 460 | 572 | |
|---|
| 461 | 573 | dsize = dp->i_df.if_bytes; |
|---|
| 462 | 574 | |
|---|
| 463 | | - switch (dp->i_d.di_format) { |
|---|
| 575 | + switch (dp->i_df.if_format) { |
|---|
| 464 | 576 | case XFS_DINODE_FMT_EXTENTS: |
|---|
| 465 | 577 | /* |
|---|
| 466 | 578 | * If there is no attr fork and the data fork is extents, |
|---|
| .. | .. |
|---|
| 493 | 605 | * A data fork btree root must have space for at least |
|---|
| 494 | 606 | * MINDBTPTRS key/ptr pairs if the data fork is small or empty. |
|---|
| 495 | 607 | */ |
|---|
| 496 | | - minforkoff = max(dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS)); |
|---|
| 608 | + minforkoff = max_t(int64_t, dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS)); |
|---|
| 497 | 609 | minforkoff = roundup(minforkoff, 8) >> 3; |
|---|
| 498 | 610 | |
|---|
| 499 | 611 | /* attr fork btree root can have at least this many key/ptr pairs */ |
|---|
| 500 | | - maxforkoff = XFS_LITINO(mp, dp->i_d.di_version) - |
|---|
| 501 | | - XFS_BMDR_SPACE_CALC(MINABTPTRS); |
|---|
| 612 | + maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS); |
|---|
| 502 | 613 | maxforkoff = maxforkoff >> 3; /* rounded down */ |
|---|
| 503 | 614 | |
|---|
| 504 | 615 | if (offset >= maxforkoff) |
|---|
| .. | .. |
|---|
| 530 | 641 | * Create the initial contents of a shortform attribute list. |
|---|
| 531 | 642 | */ |
|---|
| 532 | 643 | void |
|---|
| 533 | | -xfs_attr_shortform_create(xfs_da_args_t *args) |
|---|
| 644 | +xfs_attr_shortform_create( |
|---|
| 645 | + struct xfs_da_args *args) |
|---|
| 534 | 646 | { |
|---|
| 535 | | - xfs_attr_sf_hdr_t *hdr; |
|---|
| 536 | | - xfs_inode_t *dp; |
|---|
| 537 | | - struct xfs_ifork *ifp; |
|---|
| 647 | + struct xfs_inode *dp = args->dp; |
|---|
| 648 | + struct xfs_ifork *ifp = dp->i_afp; |
|---|
| 649 | + struct xfs_attr_sf_hdr *hdr; |
|---|
| 538 | 650 | |
|---|
| 539 | 651 | trace_xfs_attr_sf_create(args); |
|---|
| 540 | 652 | |
|---|
| 541 | | - dp = args->dp; |
|---|
| 542 | | - ASSERT(dp != NULL); |
|---|
| 543 | | - ifp = dp->i_afp; |
|---|
| 544 | | - ASSERT(ifp != NULL); |
|---|
| 545 | 653 | ASSERT(ifp->if_bytes == 0); |
|---|
| 546 | | - if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) { |
|---|
| 654 | + if (ifp->if_format == XFS_DINODE_FMT_EXTENTS) { |
|---|
| 547 | 655 | ifp->if_flags &= ~XFS_IFEXTENTS; /* just in case */ |
|---|
| 548 | | - dp->i_d.di_aformat = XFS_DINODE_FMT_LOCAL; |
|---|
| 656 | + ifp->if_format = XFS_DINODE_FMT_LOCAL; |
|---|
| 549 | 657 | ifp->if_flags |= XFS_IFINLINE; |
|---|
| 550 | 658 | } else { |
|---|
| 551 | 659 | ASSERT(ifp->if_flags & XFS_IFINLINE); |
|---|
| .. | .. |
|---|
| 558 | 666 | } |
|---|
| 559 | 667 | |
|---|
| 560 | 668 | /* |
|---|
| 669 | + * Return -EEXIST if attr is found, or -ENOATTR if not |
|---|
| 670 | + * args: args containing attribute name and namelen |
|---|
| 671 | + * sfep: If not null, pointer will be set to the last attr entry found on |
|---|
| 672 | + -EEXIST. On -ENOATTR pointer is left at the last entry in the list |
|---|
| 673 | + * basep: If not null, pointer is set to the byte offset of the entry in the |
|---|
| 674 | + * list on -EEXIST. On -ENOATTR, pointer is left at the byte offset of |
|---|
| 675 | + * the last entry in the list |
|---|
| 676 | + */ |
|---|
| 677 | +int |
|---|
| 678 | +xfs_attr_sf_findname( |
|---|
| 679 | + struct xfs_da_args *args, |
|---|
| 680 | + struct xfs_attr_sf_entry **sfep, |
|---|
| 681 | + unsigned int *basep) |
|---|
| 682 | +{ |
|---|
| 683 | + struct xfs_attr_shortform *sf; |
|---|
| 684 | + struct xfs_attr_sf_entry *sfe; |
|---|
| 685 | + unsigned int base = sizeof(struct xfs_attr_sf_hdr); |
|---|
| 686 | + int size = 0; |
|---|
| 687 | + int end; |
|---|
| 688 | + int i; |
|---|
| 689 | + |
|---|
| 690 | + sf = (struct xfs_attr_shortform *)args->dp->i_afp->if_u1.if_data; |
|---|
| 691 | + sfe = &sf->list[0]; |
|---|
| 692 | + end = sf->hdr.count; |
|---|
| 693 | + for (i = 0; i < end; sfe = xfs_attr_sf_nextentry(sfe), |
|---|
| 694 | + base += size, i++) { |
|---|
| 695 | + size = xfs_attr_sf_entsize(sfe); |
|---|
| 696 | + if (!xfs_attr_match(args, sfe->namelen, sfe->nameval, |
|---|
| 697 | + sfe->flags)) |
|---|
| 698 | + continue; |
|---|
| 699 | + break; |
|---|
| 700 | + } |
|---|
| 701 | + |
|---|
| 702 | + if (sfep != NULL) |
|---|
| 703 | + *sfep = sfe; |
|---|
| 704 | + |
|---|
| 705 | + if (basep != NULL) |
|---|
| 706 | + *basep = base; |
|---|
| 707 | + |
|---|
| 708 | + if (i == end) |
|---|
| 709 | + return -ENOATTR; |
|---|
| 710 | + return -EEXIST; |
|---|
| 711 | +} |
|---|
| 712 | + |
|---|
| 713 | +/* |
|---|
| 561 | 714 | * Add a name/value pair to the shortform attribute list. |
|---|
| 562 | 715 | * Overflow from the inode has already been checked for. |
|---|
| 563 | 716 | */ |
|---|
| 564 | 717 | void |
|---|
| 565 | | -xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff) |
|---|
| 718 | +xfs_attr_shortform_add( |
|---|
| 719 | + struct xfs_da_args *args, |
|---|
| 720 | + int forkoff) |
|---|
| 566 | 721 | { |
|---|
| 567 | | - xfs_attr_shortform_t *sf; |
|---|
| 568 | | - xfs_attr_sf_entry_t *sfe; |
|---|
| 569 | | - int i, offset, size; |
|---|
| 570 | | - xfs_mount_t *mp; |
|---|
| 571 | | - xfs_inode_t *dp; |
|---|
| 572 | | - struct xfs_ifork *ifp; |
|---|
| 722 | + struct xfs_attr_shortform *sf; |
|---|
| 723 | + struct xfs_attr_sf_entry *sfe; |
|---|
| 724 | + int offset, size; |
|---|
| 725 | + struct xfs_mount *mp; |
|---|
| 726 | + struct xfs_inode *dp; |
|---|
| 727 | + struct xfs_ifork *ifp; |
|---|
| 573 | 728 | |
|---|
| 574 | 729 | trace_xfs_attr_sf_add(args); |
|---|
| 575 | 730 | |
|---|
| .. | .. |
|---|
| 579 | 734 | |
|---|
| 580 | 735 | ifp = dp->i_afp; |
|---|
| 581 | 736 | ASSERT(ifp->if_flags & XFS_IFINLINE); |
|---|
| 582 | | - sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; |
|---|
| 583 | | - sfe = &sf->list[0]; |
|---|
| 584 | | - for (i = 0; i < sf->hdr.count; sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) { |
|---|
| 585 | | -#ifdef DEBUG |
|---|
| 586 | | - if (sfe->namelen != args->namelen) |
|---|
| 587 | | - continue; |
|---|
| 588 | | - if (memcmp(args->name, sfe->nameval, args->namelen) != 0) |
|---|
| 589 | | - continue; |
|---|
| 590 | | - if (!xfs_attr_namesp_match(args->flags, sfe->flags)) |
|---|
| 591 | | - continue; |
|---|
| 737 | + sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data; |
|---|
| 738 | + if (xfs_attr_sf_findname(args, &sfe, NULL) == -EEXIST) |
|---|
| 592 | 739 | ASSERT(0); |
|---|
| 593 | | -#endif |
|---|
| 594 | | - } |
|---|
| 595 | 740 | |
|---|
| 596 | 741 | offset = (char *)sfe - (char *)sf; |
|---|
| 597 | | - size = XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen); |
|---|
| 742 | + size = xfs_attr_sf_entsize_byname(args->namelen, args->valuelen); |
|---|
| 598 | 743 | xfs_idata_realloc(dp, size, XFS_ATTR_FORK); |
|---|
| 599 | | - sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; |
|---|
| 600 | | - sfe = (xfs_attr_sf_entry_t *)((char *)sf + offset); |
|---|
| 744 | + sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data; |
|---|
| 745 | + sfe = (struct xfs_attr_sf_entry *)((char *)sf + offset); |
|---|
| 601 | 746 | |
|---|
| 602 | 747 | sfe->namelen = args->namelen; |
|---|
| 603 | 748 | sfe->valuelen = args->valuelen; |
|---|
| 604 | | - sfe->flags = XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags); |
|---|
| 749 | + sfe->flags = args->attr_filter; |
|---|
| 605 | 750 | memcpy(sfe->nameval, args->name, args->namelen); |
|---|
| 606 | 751 | memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen); |
|---|
| 607 | 752 | sf->hdr.count++; |
|---|
| .. | .. |
|---|
| 620 | 765 | struct xfs_inode *ip, |
|---|
| 621 | 766 | struct xfs_trans *tp) |
|---|
| 622 | 767 | { |
|---|
| 623 | | - xfs_idestroy_fork(ip, XFS_ATTR_FORK); |
|---|
| 768 | + ASSERT(ip->i_afp->if_nextents == 0); |
|---|
| 769 | + |
|---|
| 770 | + xfs_idestroy_fork(ip->i_afp); |
|---|
| 771 | + kmem_cache_free(xfs_ifork_zone, ip->i_afp); |
|---|
| 772 | + ip->i_afp = NULL; |
|---|
| 624 | 773 | ip->i_d.di_forkoff = 0; |
|---|
| 625 | | - ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; |
|---|
| 626 | | - |
|---|
| 627 | | - ASSERT(ip->i_d.di_anextents == 0); |
|---|
| 628 | | - ASSERT(ip->i_afp == NULL); |
|---|
| 629 | | - |
|---|
| 630 | 774 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
|---|
| 631 | 775 | } |
|---|
| 632 | 776 | |
|---|
| .. | .. |
|---|
| 634 | 778 | * Remove an attribute from the shortform attribute list structure. |
|---|
| 635 | 779 | */ |
|---|
| 636 | 780 | int |
|---|
| 637 | | -xfs_attr_shortform_remove(xfs_da_args_t *args) |
|---|
| 781 | +xfs_attr_shortform_remove( |
|---|
| 782 | + struct xfs_da_args *args) |
|---|
| 638 | 783 | { |
|---|
| 639 | | - xfs_attr_shortform_t *sf; |
|---|
| 640 | | - xfs_attr_sf_entry_t *sfe; |
|---|
| 641 | | - int base, size=0, end, totsize, i; |
|---|
| 642 | | - xfs_mount_t *mp; |
|---|
| 643 | | - xfs_inode_t *dp; |
|---|
| 784 | + struct xfs_attr_shortform *sf; |
|---|
| 785 | + struct xfs_attr_sf_entry *sfe; |
|---|
| 786 | + int size = 0, end, totsize; |
|---|
| 787 | + unsigned int base; |
|---|
| 788 | + struct xfs_mount *mp; |
|---|
| 789 | + struct xfs_inode *dp; |
|---|
| 790 | + int error; |
|---|
| 644 | 791 | |
|---|
| 645 | 792 | trace_xfs_attr_sf_remove(args); |
|---|
| 646 | 793 | |
|---|
| 647 | 794 | dp = args->dp; |
|---|
| 648 | 795 | mp = dp->i_mount; |
|---|
| 649 | | - base = sizeof(xfs_attr_sf_hdr_t); |
|---|
| 650 | | - sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data; |
|---|
| 651 | | - sfe = &sf->list[0]; |
|---|
| 652 | | - end = sf->hdr.count; |
|---|
| 653 | | - for (i = 0; i < end; sfe = XFS_ATTR_SF_NEXTENTRY(sfe), |
|---|
| 654 | | - base += size, i++) { |
|---|
| 655 | | - size = XFS_ATTR_SF_ENTSIZE(sfe); |
|---|
| 656 | | - if (sfe->namelen != args->namelen) |
|---|
| 657 | | - continue; |
|---|
| 658 | | - if (memcmp(sfe->nameval, args->name, args->namelen) != 0) |
|---|
| 659 | | - continue; |
|---|
| 660 | | - if (!xfs_attr_namesp_match(args->flags, sfe->flags)) |
|---|
| 661 | | - continue; |
|---|
| 662 | | - break; |
|---|
| 663 | | - } |
|---|
| 664 | | - if (i == end) |
|---|
| 665 | | - return -ENOATTR; |
|---|
| 796 | + sf = (struct xfs_attr_shortform *)dp->i_afp->if_u1.if_data; |
|---|
| 797 | + |
|---|
| 798 | + error = xfs_attr_sf_findname(args, &sfe, &base); |
|---|
| 799 | + if (error != -EEXIST) |
|---|
| 800 | + return error; |
|---|
| 801 | + size = xfs_attr_sf_entsize(sfe); |
|---|
| 666 | 802 | |
|---|
| 667 | 803 | /* |
|---|
| 668 | 804 | * Fix up the attribute fork data, covering the hole |
|---|
| .. | .. |
|---|
| 680 | 816 | totsize -= size; |
|---|
| 681 | 817 | if (totsize == sizeof(xfs_attr_sf_hdr_t) && |
|---|
| 682 | 818 | (mp->m_flags & XFS_MOUNT_ATTR2) && |
|---|
| 683 | | - (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && |
|---|
| 819 | + (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) && |
|---|
| 684 | 820 | !(args->op_flags & XFS_DA_OP_ADDNAME)) { |
|---|
| 685 | 821 | xfs_attr_fork_remove(dp, args->trans); |
|---|
| 686 | 822 | } else { |
|---|
| .. | .. |
|---|
| 690 | 826 | ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || |
|---|
| 691 | 827 | (args->op_flags & XFS_DA_OP_ADDNAME) || |
|---|
| 692 | 828 | !(mp->m_flags & XFS_MOUNT_ATTR2) || |
|---|
| 693 | | - dp->i_d.di_format == XFS_DINODE_FMT_BTREE); |
|---|
| 829 | + dp->i_df.if_format == XFS_DINODE_FMT_BTREE); |
|---|
| 694 | 830 | xfs_trans_log_inode(args->trans, dp, |
|---|
| 695 | 831 | XFS_ILOG_CORE | XFS_ILOG_ADATA); |
|---|
| 696 | 832 | } |
|---|
| .. | .. |
|---|
| 707 | 843 | int |
|---|
| 708 | 844 | xfs_attr_shortform_lookup(xfs_da_args_t *args) |
|---|
| 709 | 845 | { |
|---|
| 710 | | - xfs_attr_shortform_t *sf; |
|---|
| 711 | | - xfs_attr_sf_entry_t *sfe; |
|---|
| 846 | + struct xfs_attr_shortform *sf; |
|---|
| 847 | + struct xfs_attr_sf_entry *sfe; |
|---|
| 712 | 848 | int i; |
|---|
| 713 | 849 | struct xfs_ifork *ifp; |
|---|
| 714 | 850 | |
|---|
| .. | .. |
|---|
| 716 | 852 | |
|---|
| 717 | 853 | ifp = args->dp->i_afp; |
|---|
| 718 | 854 | ASSERT(ifp->if_flags & XFS_IFINLINE); |
|---|
| 719 | | - sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; |
|---|
| 855 | + sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data; |
|---|
| 720 | 856 | sfe = &sf->list[0]; |
|---|
| 721 | 857 | for (i = 0; i < sf->hdr.count; |
|---|
| 722 | | - sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) { |
|---|
| 723 | | - if (sfe->namelen != args->namelen) |
|---|
| 724 | | - continue; |
|---|
| 725 | | - if (memcmp(args->name, sfe->nameval, args->namelen) != 0) |
|---|
| 726 | | - continue; |
|---|
| 727 | | - if (!xfs_attr_namesp_match(args->flags, sfe->flags)) |
|---|
| 728 | | - continue; |
|---|
| 729 | | - return -EEXIST; |
|---|
| 858 | + sfe = xfs_attr_sf_nextentry(sfe), i++) { |
|---|
| 859 | + if (xfs_attr_match(args, sfe->namelen, sfe->nameval, |
|---|
| 860 | + sfe->flags)) |
|---|
| 861 | + return -EEXIST; |
|---|
| 730 | 862 | } |
|---|
| 731 | 863 | return -ENOATTR; |
|---|
| 732 | 864 | } |
|---|
| 733 | 865 | |
|---|
| 734 | 866 | /* |
|---|
| 735 | | - * Look up a name in a shortform attribute list structure. |
|---|
| 867 | + * Retrieve the attribute value and length. |
|---|
| 868 | + * |
|---|
| 869 | + * If args->valuelen is zero, only the length needs to be returned. Unlike a |
|---|
| 870 | + * lookup, we only return an error if the attribute does not exist or we can't |
|---|
| 871 | + * retrieve the value. |
|---|
| 736 | 872 | */ |
|---|
| 737 | | -/*ARGSUSED*/ |
|---|
| 738 | 873 | int |
|---|
| 739 | | -xfs_attr_shortform_getvalue(xfs_da_args_t *args) |
|---|
| 874 | +xfs_attr_shortform_getvalue( |
|---|
| 875 | + struct xfs_da_args *args) |
|---|
| 740 | 876 | { |
|---|
| 741 | | - xfs_attr_shortform_t *sf; |
|---|
| 742 | | - xfs_attr_sf_entry_t *sfe; |
|---|
| 743 | | - int i; |
|---|
| 877 | + struct xfs_attr_shortform *sf; |
|---|
| 878 | + struct xfs_attr_sf_entry *sfe; |
|---|
| 879 | + int i; |
|---|
| 744 | 880 | |
|---|
| 745 | 881 | ASSERT(args->dp->i_afp->if_flags == XFS_IFINLINE); |
|---|
| 746 | | - sf = (xfs_attr_shortform_t *)args->dp->i_afp->if_u1.if_data; |
|---|
| 882 | + sf = (struct xfs_attr_shortform *)args->dp->i_afp->if_u1.if_data; |
|---|
| 747 | 883 | sfe = &sf->list[0]; |
|---|
| 748 | 884 | for (i = 0; i < sf->hdr.count; |
|---|
| 749 | | - sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) { |
|---|
| 750 | | - if (sfe->namelen != args->namelen) |
|---|
| 751 | | - continue; |
|---|
| 752 | | - if (memcmp(args->name, sfe->nameval, args->namelen) != 0) |
|---|
| 753 | | - continue; |
|---|
| 754 | | - if (!xfs_attr_namesp_match(args->flags, sfe->flags)) |
|---|
| 755 | | - continue; |
|---|
| 756 | | - if (args->flags & ATTR_KERNOVAL) { |
|---|
| 757 | | - args->valuelen = sfe->valuelen; |
|---|
| 758 | | - return -EEXIST; |
|---|
| 759 | | - } |
|---|
| 760 | | - if (args->valuelen < sfe->valuelen) { |
|---|
| 761 | | - args->valuelen = sfe->valuelen; |
|---|
| 762 | | - return -ERANGE; |
|---|
| 763 | | - } |
|---|
| 764 | | - args->valuelen = sfe->valuelen; |
|---|
| 765 | | - memcpy(args->value, &sfe->nameval[args->namelen], |
|---|
| 766 | | - args->valuelen); |
|---|
| 767 | | - return -EEXIST; |
|---|
| 885 | + sfe = xfs_attr_sf_nextentry(sfe), i++) { |
|---|
| 886 | + if (xfs_attr_match(args, sfe->namelen, sfe->nameval, |
|---|
| 887 | + sfe->flags)) |
|---|
| 888 | + return xfs_attr_copy_value(args, |
|---|
| 889 | + &sfe->nameval[args->namelen], sfe->valuelen); |
|---|
| 768 | 890 | } |
|---|
| 769 | 891 | return -ENOATTR; |
|---|
| 770 | 892 | } |
|---|
| .. | .. |
|---|
| 792 | 914 | |
|---|
| 793 | 915 | dp = args->dp; |
|---|
| 794 | 916 | ifp = dp->i_afp; |
|---|
| 795 | | - sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; |
|---|
| 917 | + sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data; |
|---|
| 796 | 918 | size = be16_to_cpu(sf->hdr.totsize); |
|---|
| 797 | | - tmpbuffer = kmem_alloc(size, KM_SLEEP); |
|---|
| 919 | + tmpbuffer = kmem_alloc(size, 0); |
|---|
| 798 | 920 | ASSERT(tmpbuffer != NULL); |
|---|
| 799 | 921 | memcpy(tmpbuffer, ifp->if_u1.if_data, size); |
|---|
| 800 | | - sf = (xfs_attr_shortform_t *)tmpbuffer; |
|---|
| 922 | + sf = (struct xfs_attr_shortform *)tmpbuffer; |
|---|
| 801 | 923 | |
|---|
| 802 | 924 | xfs_idata_realloc(dp, -size, XFS_ATTR_FORK); |
|---|
| 803 | | - xfs_bmap_local_to_extents_empty(dp, XFS_ATTR_FORK); |
|---|
| 925 | + xfs_bmap_local_to_extents_empty(args->trans, dp, XFS_ATTR_FORK); |
|---|
| 804 | 926 | |
|---|
| 805 | 927 | bp = NULL; |
|---|
| 806 | 928 | error = xfs_da_grow_inode(args, &blkno); |
|---|
| 807 | | - if (error) { |
|---|
| 808 | | - /* |
|---|
| 809 | | - * If we hit an IO error middle of the transaction inside |
|---|
| 810 | | - * grow_inode(), we may have inconsistent data. Bail out. |
|---|
| 811 | | - */ |
|---|
| 812 | | - if (error == -EIO) |
|---|
| 813 | | - goto out; |
|---|
| 814 | | - xfs_idata_realloc(dp, size, XFS_ATTR_FORK); /* try to put */ |
|---|
| 815 | | - memcpy(ifp->if_u1.if_data, tmpbuffer, size); /* it back */ |
|---|
| 929 | + if (error) |
|---|
| 816 | 930 | goto out; |
|---|
| 817 | | - } |
|---|
| 818 | 931 | |
|---|
| 819 | 932 | ASSERT(blkno == 0); |
|---|
| 820 | 933 | error = xfs_attr3_leaf_create(args, blkno, &bp); |
|---|
| 821 | | - if (error) { |
|---|
| 822 | | - /* xfs_attr3_leaf_create may not have instantiated a block */ |
|---|
| 823 | | - if (bp && (xfs_da_shrink_inode(args, 0, bp) != 0)) |
|---|
| 824 | | - goto out; |
|---|
| 825 | | - xfs_idata_realloc(dp, size, XFS_ATTR_FORK); /* try to put */ |
|---|
| 826 | | - memcpy(ifp->if_u1.if_data, tmpbuffer, size); /* it back */ |
|---|
| 934 | + if (error) |
|---|
| 827 | 935 | goto out; |
|---|
| 828 | | - } |
|---|
| 829 | 936 | |
|---|
| 830 | 937 | memset((char *)&nargs, 0, sizeof(nargs)); |
|---|
| 831 | 938 | nargs.dp = dp; |
|---|
| .. | .. |
|---|
| 843 | 950 | nargs.valuelen = sfe->valuelen; |
|---|
| 844 | 951 | nargs.hashval = xfs_da_hashname(sfe->nameval, |
|---|
| 845 | 952 | sfe->namelen); |
|---|
| 846 | | - nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags); |
|---|
| 953 | + nargs.attr_filter = sfe->flags & XFS_ATTR_NSP_ONDISK_MASK; |
|---|
| 847 | 954 | error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */ |
|---|
| 848 | 955 | ASSERT(error == -ENOATTR); |
|---|
| 849 | 956 | error = xfs_attr3_leaf_add(bp, &nargs); |
|---|
| 850 | 957 | ASSERT(error != -ENOSPC); |
|---|
| 851 | 958 | if (error) |
|---|
| 852 | 959 | goto out; |
|---|
| 853 | | - sfe = XFS_ATTR_SF_NEXTENTRY(sfe); |
|---|
| 960 | + sfe = xfs_attr_sf_nextentry(sfe); |
|---|
| 854 | 961 | } |
|---|
| 855 | 962 | error = 0; |
|---|
| 856 | 963 | *leaf_bp = bp; |
|---|
| .. | .. |
|---|
| 874 | 981 | struct xfs_attr3_icleaf_hdr leafhdr; |
|---|
| 875 | 982 | int bytes; |
|---|
| 876 | 983 | int i; |
|---|
| 877 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 984 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 878 | 985 | |
|---|
| 879 | 986 | leaf = bp->b_addr; |
|---|
| 880 | 987 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf); |
|---|
| .. | .. |
|---|
| 891 | 998 | return 0; |
|---|
| 892 | 999 | if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX) |
|---|
| 893 | 1000 | return 0; |
|---|
| 894 | | - bytes += sizeof(struct xfs_attr_sf_entry) - 1 |
|---|
| 895 | | - + name_loc->namelen |
|---|
| 896 | | - + be16_to_cpu(name_loc->valuelen); |
|---|
| 1001 | + bytes += xfs_attr_sf_entsize_byname(name_loc->namelen, |
|---|
| 1002 | + be16_to_cpu(name_loc->valuelen)); |
|---|
| 897 | 1003 | } |
|---|
| 898 | 1004 | if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) && |
|---|
| 899 | | - (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && |
|---|
| 1005 | + (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) && |
|---|
| 900 | 1006 | (bytes == sizeof(struct xfs_attr_sf_hdr))) |
|---|
| 901 | 1007 | return -1; |
|---|
| 902 | 1008 | return xfs_attr_shortform_bytesfit(dp, bytes); |
|---|
| .. | .. |
|---|
| 913 | 1019 | char *endp; |
|---|
| 914 | 1020 | struct xfs_ifork *ifp; |
|---|
| 915 | 1021 | int i; |
|---|
| 916 | | - int size; |
|---|
| 1022 | + int64_t size; |
|---|
| 917 | 1023 | |
|---|
| 918 | | - ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL); |
|---|
| 1024 | + ASSERT(ip->i_afp->if_format == XFS_DINODE_FMT_LOCAL); |
|---|
| 919 | 1025 | ifp = XFS_IFORK_PTR(ip, XFS_ATTR_FORK); |
|---|
| 920 | 1026 | sfp = (struct xfs_attr_shortform *)ifp->if_u1.if_data; |
|---|
| 921 | 1027 | size = ifp->if_bytes; |
|---|
| .. | .. |
|---|
| 938 | 1044 | * xfs_attr_sf_entry is defined with a 1-byte variable |
|---|
| 939 | 1045 | * array at the end, so we must subtract that off. |
|---|
| 940 | 1046 | */ |
|---|
| 941 | | - if (((char *)sfep + sizeof(*sfep) - 1) >= endp) |
|---|
| 1047 | + if (((char *)sfep + sizeof(*sfep)) >= endp) |
|---|
| 942 | 1048 | return __this_address; |
|---|
| 943 | 1049 | |
|---|
| 944 | 1050 | /* Don't allow names with known bad length. */ |
|---|
| .. | .. |
|---|
| 950 | 1056 | * within the data buffer. The next entry starts after the |
|---|
| 951 | 1057 | * name component, so nextentry is an acceptable test. |
|---|
| 952 | 1058 | */ |
|---|
| 953 | | - next_sfep = XFS_ATTR_SF_NEXTENTRY(sfep); |
|---|
| 1059 | + next_sfep = xfs_attr_sf_nextentry(sfep); |
|---|
| 954 | 1060 | if ((char *)next_sfep > endp) |
|---|
| 955 | 1061 | return __this_address; |
|---|
| 956 | 1062 | |
|---|
| .. | .. |
|---|
| 999 | 1105 | |
|---|
| 1000 | 1106 | trace_xfs_attr_leaf_to_sf(args); |
|---|
| 1001 | 1107 | |
|---|
| 1002 | | - tmpbuffer = kmem_alloc(args->geo->blksize, KM_SLEEP); |
|---|
| 1108 | + tmpbuffer = kmem_alloc(args->geo->blksize, 0); |
|---|
| 1003 | 1109 | if (!tmpbuffer) |
|---|
| 1004 | 1110 | return -ENOMEM; |
|---|
| 1005 | 1111 | |
|---|
| .. | .. |
|---|
| 1021 | 1127 | |
|---|
| 1022 | 1128 | if (forkoff == -1) { |
|---|
| 1023 | 1129 | ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2); |
|---|
| 1024 | | - ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE); |
|---|
| 1130 | + ASSERT(dp->i_df.if_format != XFS_DINODE_FMT_BTREE); |
|---|
| 1025 | 1131 | xfs_attr_fork_remove(dp, args->trans); |
|---|
| 1026 | 1132 | goto out; |
|---|
| 1027 | 1133 | } |
|---|
| .. | .. |
|---|
| 1051 | 1157 | nargs.value = &name_loc->nameval[nargs.namelen]; |
|---|
| 1052 | 1158 | nargs.valuelen = be16_to_cpu(name_loc->valuelen); |
|---|
| 1053 | 1159 | nargs.hashval = be32_to_cpu(entry->hashval); |
|---|
| 1054 | | - nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(entry->flags); |
|---|
| 1160 | + nargs.attr_filter = entry->flags & XFS_ATTR_NSP_ONDISK_MASK; |
|---|
| 1055 | 1161 | xfs_attr_shortform_add(&nargs, forkoff); |
|---|
| 1056 | 1162 | } |
|---|
| 1057 | 1163 | error = 0; |
|---|
| .. | .. |
|---|
| 1071 | 1177 | struct xfs_attr_leafblock *leaf; |
|---|
| 1072 | 1178 | struct xfs_attr3_icleaf_hdr icleafhdr; |
|---|
| 1073 | 1179 | struct xfs_attr_leaf_entry *entries; |
|---|
| 1074 | | - struct xfs_da_node_entry *btree; |
|---|
| 1075 | 1180 | struct xfs_da3_icnode_hdr icnodehdr; |
|---|
| 1076 | 1181 | struct xfs_da_intnode *node; |
|---|
| 1077 | 1182 | struct xfs_inode *dp = args->dp; |
|---|
| .. | .. |
|---|
| 1086 | 1191 | error = xfs_da_grow_inode(args, &blkno); |
|---|
| 1087 | 1192 | if (error) |
|---|
| 1088 | 1193 | goto out; |
|---|
| 1089 | | - error = xfs_attr3_leaf_read(args->trans, dp, 0, -1, &bp1); |
|---|
| 1194 | + error = xfs_attr3_leaf_read(args->trans, dp, 0, &bp1); |
|---|
| 1090 | 1195 | if (error) |
|---|
| 1091 | 1196 | goto out; |
|---|
| 1092 | 1197 | |
|---|
| 1093 | | - error = xfs_da_get_buf(args->trans, dp, blkno, -1, &bp2, XFS_ATTR_FORK); |
|---|
| 1198 | + error = xfs_da_get_buf(args->trans, dp, blkno, &bp2, XFS_ATTR_FORK); |
|---|
| 1094 | 1199 | if (error) |
|---|
| 1095 | 1200 | goto out; |
|---|
| 1096 | 1201 | |
|---|
| .. | .. |
|---|
| 1111 | 1216 | if (error) |
|---|
| 1112 | 1217 | goto out; |
|---|
| 1113 | 1218 | node = bp1->b_addr; |
|---|
| 1114 | | - dp->d_ops->node_hdr_from_disk(&icnodehdr, node); |
|---|
| 1115 | | - btree = dp->d_ops->node_tree_p(node); |
|---|
| 1219 | + xfs_da3_node_hdr_from_disk(mp, &icnodehdr, node); |
|---|
| 1116 | 1220 | |
|---|
| 1117 | 1221 | leaf = bp2->b_addr; |
|---|
| 1118 | 1222 | xfs_attr3_leaf_hdr_from_disk(args->geo, &icleafhdr, leaf); |
|---|
| 1119 | 1223 | entries = xfs_attr3_leaf_entryp(leaf); |
|---|
| 1120 | 1224 | |
|---|
| 1121 | 1225 | /* both on-disk, don't endian-flip twice */ |
|---|
| 1122 | | - btree[0].hashval = entries[icleafhdr.count - 1].hashval; |
|---|
| 1123 | | - btree[0].before = cpu_to_be32(blkno); |
|---|
| 1226 | + icnodehdr.btree[0].hashval = entries[icleafhdr.count - 1].hashval; |
|---|
| 1227 | + icnodehdr.btree[0].before = cpu_to_be32(blkno); |
|---|
| 1124 | 1228 | icnodehdr.count = 1; |
|---|
| 1125 | | - dp->d_ops->node_hdr_to_disk(node, &icnodehdr); |
|---|
| 1229 | + xfs_da3_node_hdr_to_disk(dp->i_mount, node, &icnodehdr); |
|---|
| 1126 | 1230 | xfs_trans_log_buf(args->trans, bp1, 0, args->geo->blksize - 1); |
|---|
| 1127 | 1231 | error = 0; |
|---|
| 1128 | 1232 | out: |
|---|
| .. | .. |
|---|
| 1152 | 1256 | |
|---|
| 1153 | 1257 | trace_xfs_attr_leaf_create(args); |
|---|
| 1154 | 1258 | |
|---|
| 1155 | | - error = xfs_da_get_buf(args->trans, args->dp, blkno, -1, &bp, |
|---|
| 1259 | + error = xfs_da_get_buf(args->trans, args->dp, blkno, &bp, |
|---|
| 1156 | 1260 | XFS_ATTR_FORK); |
|---|
| 1157 | 1261 | if (error) |
|---|
| 1158 | 1262 | return error; |
|---|
| .. | .. |
|---|
| 1378 | 1482 | entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base + |
|---|
| 1379 | 1483 | ichdr->freemap[mapindex].size); |
|---|
| 1380 | 1484 | entry->hashval = cpu_to_be32(args->hashval); |
|---|
| 1381 | | - entry->flags = tmp ? XFS_ATTR_LOCAL : 0; |
|---|
| 1382 | | - entry->flags |= XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags); |
|---|
| 1485 | + entry->flags = args->attr_filter; |
|---|
| 1486 | + if (tmp) |
|---|
| 1487 | + entry->flags |= XFS_ATTR_LOCAL; |
|---|
| 1383 | 1488 | if (args->op_flags & XFS_DA_OP_RENAME) { |
|---|
| 1384 | 1489 | entry->flags |= XFS_ATTR_INCOMPLETE; |
|---|
| 1385 | 1490 | if ((args->blkno2 == args->blkno) && |
|---|
| .. | .. |
|---|
| 1464 | 1569 | |
|---|
| 1465 | 1570 | trace_xfs_attr_leaf_compact(args); |
|---|
| 1466 | 1571 | |
|---|
| 1467 | | - tmpbuffer = kmem_alloc(args->geo->blksize, KM_SLEEP); |
|---|
| 1572 | + tmpbuffer = kmem_alloc(args->geo->blksize, 0); |
|---|
| 1468 | 1573 | memcpy(tmpbuffer, bp->b_addr, args->geo->blksize); |
|---|
| 1469 | 1574 | memset(bp->b_addr, 0, args->geo->blksize); |
|---|
| 1470 | 1575 | leaf_src = (xfs_attr_leafblock_t *)tmpbuffer; |
|---|
| .. | .. |
|---|
| 1538 | 1643 | { |
|---|
| 1539 | 1644 | struct xfs_attr3_icleaf_hdr ichdr1; |
|---|
| 1540 | 1645 | struct xfs_attr3_icleaf_hdr ichdr2; |
|---|
| 1541 | | - struct xfs_mount *mp = leaf1_bp->b_target->bt_mount; |
|---|
| 1646 | + struct xfs_mount *mp = leaf1_bp->b_mount; |
|---|
| 1542 | 1647 | |
|---|
| 1543 | 1648 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr1, leaf1_bp->b_addr); |
|---|
| 1544 | 1649 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr2, leaf2_bp->b_addr); |
|---|
| .. | .. |
|---|
| 1924 | 2029 | if (blkno == 0) |
|---|
| 1925 | 2030 | continue; |
|---|
| 1926 | 2031 | error = xfs_attr3_leaf_read(state->args->trans, state->args->dp, |
|---|
| 1927 | | - blkno, -1, &bp); |
|---|
| 2032 | + blkno, &bp); |
|---|
| 1928 | 2033 | if (error) |
|---|
| 1929 | 2034 | return error; |
|---|
| 1930 | 2035 | |
|---|
| .. | .. |
|---|
| 2183 | 2288 | struct xfs_attr_leafblock *tmp_leaf; |
|---|
| 2184 | 2289 | struct xfs_attr3_icleaf_hdr tmphdr; |
|---|
| 2185 | 2290 | |
|---|
| 2186 | | - tmp_leaf = kmem_zalloc(state->args->geo->blksize, KM_SLEEP); |
|---|
| 2291 | + tmp_leaf = kmem_zalloc(state->args->geo->blksize, 0); |
|---|
| 2187 | 2292 | |
|---|
| 2188 | 2293 | /* |
|---|
| 2189 | 2294 | * Copy the header into the temp leaf so that all the stuff |
|---|
| .. | .. |
|---|
| 2274 | 2379 | leaf = bp->b_addr; |
|---|
| 2275 | 2380 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); |
|---|
| 2276 | 2381 | entries = xfs_attr3_leaf_entryp(leaf); |
|---|
| 2277 | | - if (ichdr.count >= args->geo->blksize / 8) |
|---|
| 2382 | + if (ichdr.count >= args->geo->blksize / 8) { |
|---|
| 2383 | + xfs_buf_mark_corrupt(bp); |
|---|
| 2278 | 2384 | return -EFSCORRUPTED; |
|---|
| 2385 | + } |
|---|
| 2279 | 2386 | |
|---|
| 2280 | 2387 | /* |
|---|
| 2281 | 2388 | * Binary search. (note: small blocks will skip this loop) |
|---|
| .. | .. |
|---|
| 2291 | 2398 | else |
|---|
| 2292 | 2399 | break; |
|---|
| 2293 | 2400 | } |
|---|
| 2294 | | - if (!(probe >= 0 && (!ichdr.count || probe < ichdr.count))) |
|---|
| 2401 | + if (!(probe >= 0 && (!ichdr.count || probe < ichdr.count))) { |
|---|
| 2402 | + xfs_buf_mark_corrupt(bp); |
|---|
| 2295 | 2403 | return -EFSCORRUPTED; |
|---|
| 2296 | | - if (!(span <= 4 || be32_to_cpu(entry->hashval) == hashval)) |
|---|
| 2404 | + } |
|---|
| 2405 | + if (!(span <= 4 || be32_to_cpu(entry->hashval) == hashval)) { |
|---|
| 2406 | + xfs_buf_mark_corrupt(bp); |
|---|
| 2297 | 2407 | return -EFSCORRUPTED; |
|---|
| 2408 | + } |
|---|
| 2298 | 2409 | |
|---|
| 2299 | 2410 | /* |
|---|
| 2300 | 2411 | * Since we may have duplicate hashval's, find the first matching |
|---|
| .. | .. |
|---|
| 2322 | 2433 | /* |
|---|
| 2323 | 2434 | * GROT: Add code to remove incomplete entries. |
|---|
| 2324 | 2435 | */ |
|---|
| 2325 | | - /* |
|---|
| 2326 | | - * If we are looking for INCOMPLETE entries, show only those. |
|---|
| 2327 | | - * If we are looking for complete entries, show only those. |
|---|
| 2328 | | - */ |
|---|
| 2329 | | - if ((args->flags & XFS_ATTR_INCOMPLETE) != |
|---|
| 2330 | | - (entry->flags & XFS_ATTR_INCOMPLETE)) { |
|---|
| 2331 | | - continue; |
|---|
| 2332 | | - } |
|---|
| 2333 | 2436 | if (entry->flags & XFS_ATTR_LOCAL) { |
|---|
| 2334 | 2437 | name_loc = xfs_attr3_leaf_name_local(leaf, probe); |
|---|
| 2335 | | - if (name_loc->namelen != args->namelen) |
|---|
| 2336 | | - continue; |
|---|
| 2337 | | - if (memcmp(args->name, name_loc->nameval, |
|---|
| 2338 | | - args->namelen) != 0) |
|---|
| 2339 | | - continue; |
|---|
| 2340 | | - if (!xfs_attr_namesp_match(args->flags, entry->flags)) |
|---|
| 2438 | + if (!xfs_attr_match(args, name_loc->namelen, |
|---|
| 2439 | + name_loc->nameval, entry->flags)) |
|---|
| 2341 | 2440 | continue; |
|---|
| 2342 | 2441 | args->index = probe; |
|---|
| 2343 | 2442 | return -EEXIST; |
|---|
| 2344 | 2443 | } else { |
|---|
| 2345 | 2444 | name_rmt = xfs_attr3_leaf_name_remote(leaf, probe); |
|---|
| 2346 | | - if (name_rmt->namelen != args->namelen) |
|---|
| 2347 | | - continue; |
|---|
| 2348 | | - if (memcmp(args->name, name_rmt->name, |
|---|
| 2349 | | - args->namelen) != 0) |
|---|
| 2350 | | - continue; |
|---|
| 2351 | | - if (!xfs_attr_namesp_match(args->flags, entry->flags)) |
|---|
| 2445 | + if (!xfs_attr_match(args, name_rmt->namelen, |
|---|
| 2446 | + name_rmt->name, entry->flags)) |
|---|
| 2352 | 2447 | continue; |
|---|
| 2353 | 2448 | args->index = probe; |
|---|
| 2354 | 2449 | args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen); |
|---|
| .. | .. |
|---|
| 2366 | 2461 | /* |
|---|
| 2367 | 2462 | * Get the value associated with an attribute name from a leaf attribute |
|---|
| 2368 | 2463 | * list structure. |
|---|
| 2464 | + * |
|---|
| 2465 | + * If args->valuelen is zero, only the length needs to be returned. Unlike a |
|---|
| 2466 | + * lookup, we only return an error if the attribute does not exist or we can't |
|---|
| 2467 | + * retrieve the value. |
|---|
| 2369 | 2468 | */ |
|---|
| 2370 | 2469 | int |
|---|
| 2371 | 2470 | xfs_attr3_leaf_getvalue( |
|---|
| .. | .. |
|---|
| 2377 | 2476 | struct xfs_attr_leaf_entry *entry; |
|---|
| 2378 | 2477 | struct xfs_attr_leaf_name_local *name_loc; |
|---|
| 2379 | 2478 | struct xfs_attr_leaf_name_remote *name_rmt; |
|---|
| 2380 | | - int valuelen; |
|---|
| 2381 | 2479 | |
|---|
| 2382 | 2480 | leaf = bp->b_addr; |
|---|
| 2383 | 2481 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); |
|---|
| .. | .. |
|---|
| 2389 | 2487 | name_loc = xfs_attr3_leaf_name_local(leaf, args->index); |
|---|
| 2390 | 2488 | ASSERT(name_loc->namelen == args->namelen); |
|---|
| 2391 | 2489 | ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0); |
|---|
| 2392 | | - valuelen = be16_to_cpu(name_loc->valuelen); |
|---|
| 2393 | | - if (args->flags & ATTR_KERNOVAL) { |
|---|
| 2394 | | - args->valuelen = valuelen; |
|---|
| 2395 | | - return 0; |
|---|
| 2396 | | - } |
|---|
| 2397 | | - if (args->valuelen < valuelen) { |
|---|
| 2398 | | - args->valuelen = valuelen; |
|---|
| 2399 | | - return -ERANGE; |
|---|
| 2400 | | - } |
|---|
| 2401 | | - args->valuelen = valuelen; |
|---|
| 2402 | | - memcpy(args->value, &name_loc->nameval[args->namelen], valuelen); |
|---|
| 2403 | | - } else { |
|---|
| 2404 | | - name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index); |
|---|
| 2405 | | - ASSERT(name_rmt->namelen == args->namelen); |
|---|
| 2406 | | - ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0); |
|---|
| 2407 | | - args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen); |
|---|
| 2408 | | - args->rmtblkno = be32_to_cpu(name_rmt->valueblk); |
|---|
| 2409 | | - args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount, |
|---|
| 2410 | | - args->rmtvaluelen); |
|---|
| 2411 | | - if (args->flags & ATTR_KERNOVAL) { |
|---|
| 2412 | | - args->valuelen = args->rmtvaluelen; |
|---|
| 2413 | | - return 0; |
|---|
| 2414 | | - } |
|---|
| 2415 | | - if (args->valuelen < args->rmtvaluelen) { |
|---|
| 2416 | | - args->valuelen = args->rmtvaluelen; |
|---|
| 2417 | | - return -ERANGE; |
|---|
| 2418 | | - } |
|---|
| 2419 | | - args->valuelen = args->rmtvaluelen; |
|---|
| 2490 | + return xfs_attr_copy_value(args, |
|---|
| 2491 | + &name_loc->nameval[args->namelen], |
|---|
| 2492 | + be16_to_cpu(name_loc->valuelen)); |
|---|
| 2420 | 2493 | } |
|---|
| 2421 | | - return 0; |
|---|
| 2494 | + |
|---|
| 2495 | + name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index); |
|---|
| 2496 | + ASSERT(name_rmt->namelen == args->namelen); |
|---|
| 2497 | + ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0); |
|---|
| 2498 | + args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen); |
|---|
| 2499 | + args->rmtblkno = be32_to_cpu(name_rmt->valueblk); |
|---|
| 2500 | + args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount, |
|---|
| 2501 | + args->rmtvaluelen); |
|---|
| 2502 | + return xfs_attr_copy_value(args, NULL, args->rmtvaluelen); |
|---|
| 2422 | 2503 | } |
|---|
| 2423 | 2504 | |
|---|
| 2424 | 2505 | /*======================================================================== |
|---|
| .. | .. |
|---|
| 2581 | 2662 | { |
|---|
| 2582 | 2663 | struct xfs_attr3_icleaf_hdr ichdr; |
|---|
| 2583 | 2664 | struct xfs_attr_leaf_entry *entries; |
|---|
| 2584 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 2665 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 2585 | 2666 | |
|---|
| 2586 | 2667 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, bp->b_addr); |
|---|
| 2587 | 2668 | entries = xfs_attr3_leaf_entryp(bp->b_addr); |
|---|
| .. | .. |
|---|
| 2668 | 2749 | /* |
|---|
| 2669 | 2750 | * Set up the operation. |
|---|
| 2670 | 2751 | */ |
|---|
| 2671 | | - error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp); |
|---|
| 2752 | + error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, &bp); |
|---|
| 2672 | 2753 | if (error) |
|---|
| 2673 | 2754 | return error; |
|---|
| 2674 | 2755 | |
|---|
| .. | .. |
|---|
| 2708 | 2789 | XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); |
|---|
| 2709 | 2790 | } |
|---|
| 2710 | 2791 | |
|---|
| 2711 | | - /* |
|---|
| 2712 | | - * Commit the flag value change and start the next trans in series. |
|---|
| 2713 | | - */ |
|---|
| 2714 | | - return xfs_trans_roll_inode(&args->trans, args->dp); |
|---|
| 2792 | + return 0; |
|---|
| 2715 | 2793 | } |
|---|
| 2716 | 2794 | |
|---|
| 2717 | 2795 | /* |
|---|
| .. | .. |
|---|
| 2735 | 2813 | /* |
|---|
| 2736 | 2814 | * Set up the operation. |
|---|
| 2737 | 2815 | */ |
|---|
| 2738 | | - error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp); |
|---|
| 2816 | + error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, &bp); |
|---|
| 2739 | 2817 | if (error) |
|---|
| 2740 | 2818 | return error; |
|---|
| 2741 | 2819 | |
|---|
| .. | .. |
|---|
| 2759 | 2837 | XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); |
|---|
| 2760 | 2838 | } |
|---|
| 2761 | 2839 | |
|---|
| 2762 | | - /* |
|---|
| 2763 | | - * Commit the flag value change and start the next trans in series. |
|---|
| 2764 | | - */ |
|---|
| 2765 | | - return xfs_trans_roll_inode(&args->trans, args->dp); |
|---|
| 2840 | + return 0; |
|---|
| 2766 | 2841 | } |
|---|
| 2767 | 2842 | |
|---|
| 2768 | 2843 | /* |
|---|
| .. | .. |
|---|
| 2797 | 2872 | /* |
|---|
| 2798 | 2873 | * Read the block containing the "old" attr |
|---|
| 2799 | 2874 | */ |
|---|
| 2800 | | - error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp1); |
|---|
| 2875 | + error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, &bp1); |
|---|
| 2801 | 2876 | if (error) |
|---|
| 2802 | 2877 | return error; |
|---|
| 2803 | 2878 | |
|---|
| .. | .. |
|---|
| 2806 | 2881 | */ |
|---|
| 2807 | 2882 | if (args->blkno2 != args->blkno) { |
|---|
| 2808 | 2883 | error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno2, |
|---|
| 2809 | | - -1, &bp2); |
|---|
| 2884 | + &bp2); |
|---|
| 2810 | 2885 | if (error) |
|---|
| 2811 | 2886 | return error; |
|---|
| 2812 | 2887 | } else { |
|---|
| .. | .. |
|---|
| 2877 | 2952 | XFS_DA_LOGRANGE(leaf2, name_rmt, sizeof(*name_rmt))); |
|---|
| 2878 | 2953 | } |
|---|
| 2879 | 2954 | |
|---|
| 2880 | | - /* |
|---|
| 2881 | | - * Commit the flag value change and start the next trans in series. |
|---|
| 2882 | | - */ |
|---|
| 2883 | | - error = xfs_trans_roll_inode(&args->trans, args->dp); |
|---|
| 2884 | | - |
|---|
| 2885 | | - return error; |
|---|
| 2955 | + return 0; |
|---|
| 2886 | 2956 | } |
|---|