diff options
Diffstat (limited to 'fs/xfs/xfs_attr.c')
-rw-r--r-- | fs/xfs/xfs_attr.c | 97 |
1 files changed, 35 insertions, 62 deletions
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 01f226710079..a96e27bfc58b 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c | |||
@@ -416,21 +416,34 @@ out: | |||
416 | * Generic handler routine to remove a name from an attribute list. | 416 | * Generic handler routine to remove a name from an attribute list. |
417 | * Transitions attribute list from Btree to shortform as necessary. | 417 | * Transitions attribute list from Btree to shortform as necessary. |
418 | */ | 418 | */ |
419 | STATIC int | 419 | int |
420 | xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) | 420 | xfs_attr_remove( |
421 | struct xfs_inode *dp, | ||
422 | const unsigned char *name, | ||
423 | int flags) | ||
421 | { | 424 | { |
422 | xfs_da_args_t args; | 425 | struct xfs_mount *mp = dp->i_mount; |
423 | xfs_fsblock_t firstblock; | 426 | struct xfs_da_args args; |
424 | xfs_bmap_free_t flist; | 427 | struct xfs_bmap_free flist; |
425 | int error; | 428 | struct xfs_name xname; |
426 | xfs_mount_t *mp = dp->i_mount; | 429 | xfs_fsblock_t firstblock; |
430 | int error; | ||
427 | 431 | ||
428 | /* | 432 | XFS_STATS_INC(xs_attr_remove); |
429 | * Fill in the arg structure for this request. | 433 | |
430 | */ | 434 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) |
431 | memset((char *)&args, 0, sizeof(args)); | 435 | return EIO; |
432 | args.name = name->name; | 436 | |
433 | args.namelen = name->len; | 437 | if (!xfs_inode_hasattr(dp)) |
438 | return ENOATTR; | ||
439 | |||
440 | error = xfs_attr_name_to_xname(&xname, name); | ||
441 | if (error) | ||
442 | return error; | ||
443 | |||
444 | memset(&args, 0, sizeof(args)); | ||
445 | args.name = xname.name; | ||
446 | args.namelen = xname.len; | ||
434 | args.flags = flags; | 447 | args.flags = flags; |
435 | args.hashval = xfs_da_hashname(args.name, args.namelen); | 448 | args.hashval = xfs_da_hashname(args.name, args.namelen); |
436 | args.dp = dp; | 449 | args.dp = dp; |
@@ -446,9 +459,6 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) | |||
446 | */ | 459 | */ |
447 | args.op_flags = XFS_DA_OP_OKNOENT; | 460 | args.op_flags = XFS_DA_OP_OKNOENT; |
448 | 461 | ||
449 | /* | ||
450 | * Attach the dquots to the inode. | ||
451 | */ | ||
452 | error = xfs_qm_dqattach(dp, 0); | 462 | error = xfs_qm_dqattach(dp, 0); |
453 | if (error) | 463 | if (error) |
454 | return error; | 464 | return error; |
@@ -477,7 +487,7 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) | |||
477 | XFS_ATTRRM_SPACE_RES(mp), 0); | 487 | XFS_ATTRRM_SPACE_RES(mp), 0); |
478 | if (error) { | 488 | if (error) { |
479 | xfs_trans_cancel(args.trans, 0); | 489 | xfs_trans_cancel(args.trans, 0); |
480 | return(error); | 490 | return error; |
481 | } | 491 | } |
482 | 492 | ||
483 | xfs_ilock(dp, XFS_ILOCK_EXCL); | 493 | xfs_ilock(dp, XFS_ILOCK_EXCL); |
@@ -487,35 +497,26 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) | |||
487 | */ | 497 | */ |
488 | xfs_trans_ijoin(args.trans, dp, 0); | 498 | xfs_trans_ijoin(args.trans, dp, 0); |
489 | 499 | ||
490 | /* | ||
491 | * Decide on what work routines to call based on the inode size. | ||
492 | */ | ||
493 | if (!xfs_inode_hasattr(dp)) { | 500 | if (!xfs_inode_hasattr(dp)) { |
494 | error = XFS_ERROR(ENOATTR); | 501 | error = XFS_ERROR(ENOATTR); |
495 | goto out; | 502 | } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { |
496 | } | ||
497 | if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { | ||
498 | ASSERT(dp->i_afp->if_flags & XFS_IFINLINE); | 503 | ASSERT(dp->i_afp->if_flags & XFS_IFINLINE); |
499 | error = xfs_attr_shortform_remove(&args); | 504 | error = xfs_attr_shortform_remove(&args); |
500 | if (error) { | ||
501 | goto out; | ||
502 | } | ||
503 | } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { | 505 | } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { |
504 | error = xfs_attr_leaf_removename(&args); | 506 | error = xfs_attr_leaf_removename(&args); |
505 | } else { | 507 | } else { |
506 | error = xfs_attr_node_removename(&args); | 508 | error = xfs_attr_node_removename(&args); |
507 | } | 509 | } |
508 | if (error) { | 510 | |
511 | if (error) | ||
509 | goto out; | 512 | goto out; |
510 | } | ||
511 | 513 | ||
512 | /* | 514 | /* |
513 | * If this is a synchronous mount, make sure that the | 515 | * If this is a synchronous mount, make sure that the |
514 | * transaction goes to disk before returning to the user. | 516 | * transaction goes to disk before returning to the user. |
515 | */ | 517 | */ |
516 | if (mp->m_flags & XFS_MOUNT_WSYNC) { | 518 | if (mp->m_flags & XFS_MOUNT_WSYNC) |
517 | xfs_trans_set_sync(args.trans); | 519 | xfs_trans_set_sync(args.trans); |
518 | } | ||
519 | 520 | ||
520 | if ((flags & ATTR_KERNOTIME) == 0) | 521 | if ((flags & ATTR_KERNOTIME) == 0) |
521 | xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG); | 522 | xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG); |
@@ -527,45 +528,17 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) | |||
527 | error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); | 528 | error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); |
528 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | 529 | xfs_iunlock(dp, XFS_ILOCK_EXCL); |
529 | 530 | ||
530 | return(error); | 531 | return error; |
531 | 532 | ||
532 | out: | 533 | out: |
533 | if (args.trans) | 534 | if (args.trans) { |
534 | xfs_trans_cancel(args.trans, | 535 | xfs_trans_cancel(args.trans, |
535 | XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); | 536 | XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); |
536 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | ||
537 | return(error); | ||
538 | } | ||
539 | |||
540 | int | ||
541 | xfs_attr_remove( | ||
542 | xfs_inode_t *dp, | ||
543 | const unsigned char *name, | ||
544 | int flags) | ||
545 | { | ||
546 | int error; | ||
547 | struct xfs_name xname; | ||
548 | |||
549 | XFS_STATS_INC(xs_attr_remove); | ||
550 | |||
551 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) | ||
552 | return (EIO); | ||
553 | |||
554 | error = xfs_attr_name_to_xname(&xname, name); | ||
555 | if (error) | ||
556 | return error; | ||
557 | |||
558 | xfs_ilock(dp, XFS_ILOCK_SHARED); | ||
559 | if (!xfs_inode_hasattr(dp)) { | ||
560 | xfs_iunlock(dp, XFS_ILOCK_SHARED); | ||
561 | return XFS_ERROR(ENOATTR); | ||
562 | } | 537 | } |
563 | xfs_iunlock(dp, XFS_ILOCK_SHARED); | 538 | xfs_iunlock(dp, XFS_ILOCK_EXCL); |
564 | 539 | return error; | |
565 | return xfs_attr_remove_int(dp, &xname, flags); | ||
566 | } | 540 | } |
567 | 541 | ||
568 | |||
569 | /*======================================================================== | 542 | /*======================================================================== |
570 | * External routines when attribute list is inside the inode | 543 | * External routines when attribute list is inside the inode |
571 | *========================================================================*/ | 544 | *========================================================================*/ |