diff options
Diffstat (limited to 'fs/xfs/xfs_symlink.c')
| -rw-r--r-- | fs/xfs/xfs_symlink.c | 51 |
1 files changed, 48 insertions, 3 deletions
diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 195a403e1522..e830fb56e27f 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c | |||
| @@ -358,7 +358,8 @@ xfs_symlink( | |||
| 358 | int n; | 358 | int n; |
| 359 | xfs_buf_t *bp; | 359 | xfs_buf_t *bp; |
| 360 | prid_t prid; | 360 | prid_t prid; |
| 361 | struct xfs_dquot *udqp, *gdqp; | 361 | struct xfs_dquot *udqp = NULL; |
| 362 | struct xfs_dquot *gdqp = NULL; | ||
| 362 | uint resblks; | 363 | uint resblks; |
| 363 | 364 | ||
| 364 | *ipp = NULL; | 365 | *ipp = NULL; |
| @@ -585,7 +586,7 @@ xfs_symlink( | |||
| 585 | /* | 586 | /* |
| 586 | * Free a symlink that has blocks associated with it. | 587 | * Free a symlink that has blocks associated with it. |
| 587 | */ | 588 | */ |
| 588 | int | 589 | STATIC int |
| 589 | xfs_inactive_symlink_rmt( | 590 | xfs_inactive_symlink_rmt( |
| 590 | xfs_inode_t *ip, | 591 | xfs_inode_t *ip, |
| 591 | xfs_trans_t **tpp) | 592 | xfs_trans_t **tpp) |
| @@ -606,7 +607,7 @@ xfs_inactive_symlink_rmt( | |||
| 606 | 607 | ||
| 607 | tp = *tpp; | 608 | tp = *tpp; |
| 608 | mp = ip->i_mount; | 609 | mp = ip->i_mount; |
| 609 | ASSERT(ip->i_d.di_size > XFS_IFORK_DSIZE(ip)); | 610 | ASSERT(ip->i_df.if_flags & XFS_IFEXTENTS); |
| 610 | /* | 611 | /* |
| 611 | * We're freeing a symlink that has some | 612 | * We're freeing a symlink that has some |
| 612 | * blocks allocated to it. Free the | 613 | * blocks allocated to it. Free the |
| @@ -720,3 +721,47 @@ xfs_inactive_symlink_rmt( | |||
| 720 | error0: | 721 | error0: |
| 721 | return error; | 722 | return error; |
| 722 | } | 723 | } |
| 724 | |||
| 725 | /* | ||
| 726 | * xfs_inactive_symlink - free a symlink | ||
| 727 | */ | ||
| 728 | int | ||
| 729 | xfs_inactive_symlink( | ||
| 730 | struct xfs_inode *ip, | ||
| 731 | struct xfs_trans **tp) | ||
| 732 | { | ||
| 733 | struct xfs_mount *mp = ip->i_mount; | ||
| 734 | int pathlen; | ||
| 735 | |||
| 736 | trace_xfs_inactive_symlink(ip); | ||
| 737 | |||
| 738 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); | ||
| 739 | |||
| 740 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
| 741 | return XFS_ERROR(EIO); | ||
| 742 | |||
| 743 | /* | ||
| 744 | * Zero length symlinks _can_ exist. | ||
| 745 | */ | ||
| 746 | pathlen = (int)ip->i_d.di_size; | ||
| 747 | if (!pathlen) | ||
| 748 | return 0; | ||
| 749 | |||
| 750 | if (pathlen < 0 || pathlen > MAXPATHLEN) { | ||
| 751 | xfs_alert(mp, "%s: inode (0x%llx) bad symlink length (%d)", | ||
| 752 | __func__, (unsigned long long)ip->i_ino, pathlen); | ||
| 753 | ASSERT(0); | ||
| 754 | return XFS_ERROR(EFSCORRUPTED); | ||
| 755 | } | ||
| 756 | |||
| 757 | if (ip->i_df.if_flags & XFS_IFINLINE) { | ||
| 758 | if (ip->i_df.if_bytes > 0) | ||
| 759 | xfs_idata_realloc(ip, -(ip->i_df.if_bytes), | ||
| 760 | XFS_DATA_FORK); | ||
| 761 | ASSERT(ip->i_df.if_bytes == 0); | ||
| 762 | return 0; | ||
| 763 | } | ||
| 764 | |||
| 765 | /* remove the remote symlink */ | ||
| 766 | return xfs_inactive_symlink_rmt(ip, tp); | ||
| 767 | } | ||
