diff options
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
| -rw-r--r-- | fs/xfs/xfs_vnodeops.c | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index ce9268a2f56b..ebdb88840a47 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
| @@ -131,7 +131,8 @@ xfs_readlink( | |||
| 131 | __func__, (unsigned long long) ip->i_ino, | 131 | __func__, (unsigned long long) ip->i_ino, |
| 132 | (long long) pathlen); | 132 | (long long) pathlen); |
| 133 | ASSERT(0); | 133 | ASSERT(0); |
| 134 | return XFS_ERROR(EFSCORRUPTED); | 134 | error = XFS_ERROR(EFSCORRUPTED); |
| 135 | goto out; | ||
| 135 | } | 136 | } |
| 136 | 137 | ||
| 137 | 138 | ||
| @@ -175,7 +176,7 @@ xfs_free_eofblocks( | |||
| 175 | * Figure out if there are any blocks beyond the end | 176 | * Figure out if there are any blocks beyond the end |
| 176 | * of the file. If not, then there is nothing to do. | 177 | * of the file. If not, then there is nothing to do. |
| 177 | */ | 178 | */ |
| 178 | end_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)ip->i_size)); | 179 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_ISIZE(ip)); |
| 179 | last_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp)); | 180 | last_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp)); |
| 180 | if (last_fsb <= end_fsb) | 181 | if (last_fsb <= end_fsb) |
| 181 | return 0; | 182 | return 0; |
| @@ -226,7 +227,14 @@ xfs_free_eofblocks( | |||
| 226 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 227 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
| 227 | xfs_trans_ijoin(tp, ip, 0); | 228 | xfs_trans_ijoin(tp, ip, 0); |
| 228 | 229 | ||
| 229 | error = xfs_itruncate_data(&tp, ip, ip->i_size); | 230 | /* |
| 231 | * Do not update the on-disk file size. If we update the | ||
| 232 | * on-disk file size and then the system crashes before the | ||
| 233 | * contents of the file are flushed to disk then the files | ||
| 234 | * may be full of holes (ie NULL files bug). | ||
| 235 | */ | ||
| 236 | error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, | ||
| 237 | XFS_ISIZE(ip)); | ||
| 230 | if (error) { | 238 | if (error) { |
| 231 | /* | 239 | /* |
| 232 | * If we get an error at this point we simply don't | 240 | * If we get an error at this point we simply don't |
| @@ -540,8 +548,8 @@ xfs_release( | |||
| 540 | return 0; | 548 | return 0; |
| 541 | 549 | ||
| 542 | if ((S_ISREG(ip->i_d.di_mode) && | 550 | if ((S_ISREG(ip->i_d.di_mode) && |
| 543 | ((ip->i_size > 0) || (VN_CACHED(VFS_I(ip)) > 0 || | 551 | (VFS_I(ip)->i_size > 0 || |
| 544 | ip->i_delayed_blks > 0)) && | 552 | (VN_CACHED(VFS_I(ip)) > 0 || ip->i_delayed_blks > 0)) && |
| 545 | (ip->i_df.if_flags & XFS_IFEXTENTS)) && | 553 | (ip->i_df.if_flags & XFS_IFEXTENTS)) && |
| 546 | (!(ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) { | 554 | (!(ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) { |
| 547 | 555 | ||
| @@ -618,7 +626,7 @@ xfs_inactive( | |||
| 618 | * only one with a reference to the inode. | 626 | * only one with a reference to the inode. |
| 619 | */ | 627 | */ |
| 620 | truncate = ((ip->i_d.di_nlink == 0) && | 628 | truncate = ((ip->i_d.di_nlink == 0) && |
| 621 | ((ip->i_d.di_size != 0) || (ip->i_size != 0) || | 629 | ((ip->i_d.di_size != 0) || XFS_ISIZE(ip) != 0 || |
| 622 | (ip->i_d.di_nextents > 0) || (ip->i_delayed_blks > 0)) && | 630 | (ip->i_d.di_nextents > 0) || (ip->i_delayed_blks > 0)) && |
| 623 | S_ISREG(ip->i_d.di_mode)); | 631 | S_ISREG(ip->i_d.di_mode)); |
| 624 | 632 | ||
| @@ -632,12 +640,12 @@ xfs_inactive( | |||
| 632 | 640 | ||
| 633 | if (ip->i_d.di_nlink != 0) { | 641 | if (ip->i_d.di_nlink != 0) { |
| 634 | if ((S_ISREG(ip->i_d.di_mode) && | 642 | if ((S_ISREG(ip->i_d.di_mode) && |
| 635 | ((ip->i_size > 0) || (VN_CACHED(VFS_I(ip)) > 0 || | 643 | (VFS_I(ip)->i_size > 0 || |
| 636 | ip->i_delayed_blks > 0)) && | 644 | (VN_CACHED(VFS_I(ip)) > 0 || ip->i_delayed_blks > 0)) && |
| 637 | (ip->i_df.if_flags & XFS_IFEXTENTS) && | 645 | (ip->i_df.if_flags & XFS_IFEXTENTS) && |
| 638 | (!(ip->i_d.di_flags & | 646 | (!(ip->i_d.di_flags & |
| 639 | (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) || | 647 | (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) || |
| 640 | (ip->i_delayed_blks != 0)))) { | 648 | ip->i_delayed_blks != 0))) { |
| 641 | error = xfs_free_eofblocks(mp, ip, 0); | 649 | error = xfs_free_eofblocks(mp, ip, 0); |
| 642 | if (error) | 650 | if (error) |
| 643 | return VN_INACTIVE_CACHE; | 651 | return VN_INACTIVE_CACHE; |
| @@ -670,13 +678,18 @@ xfs_inactive( | |||
| 670 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 678 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
| 671 | xfs_trans_ijoin(tp, ip, 0); | 679 | xfs_trans_ijoin(tp, ip, 0); |
| 672 | 680 | ||
| 673 | error = xfs_itruncate_data(&tp, ip, 0); | 681 | ip->i_d.di_size = 0; |
| 682 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | ||
| 683 | |||
| 684 | error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, 0); | ||
| 674 | if (error) { | 685 | if (error) { |
| 675 | xfs_trans_cancel(tp, | 686 | xfs_trans_cancel(tp, |
| 676 | XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); | 687 | XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); |
| 677 | xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); | 688 | xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); |
| 678 | return VN_INACTIVE_CACHE; | 689 | return VN_INACTIVE_CACHE; |
| 679 | } | 690 | } |
| 691 | |||
| 692 | ASSERT(ip->i_d.di_nextents == 0); | ||
| 680 | } else if (S_ISLNK(ip->i_d.di_mode)) { | 693 | } else if (S_ISLNK(ip->i_d.di_mode)) { |
| 681 | 694 | ||
| 682 | /* | 695 | /* |
| @@ -822,7 +835,7 @@ int | |||
| 822 | xfs_create( | 835 | xfs_create( |
| 823 | xfs_inode_t *dp, | 836 | xfs_inode_t *dp, |
| 824 | struct xfs_name *name, | 837 | struct xfs_name *name, |
| 825 | mode_t mode, | 838 | umode_t mode, |
| 826 | xfs_dev_t rdev, | 839 | xfs_dev_t rdev, |
| 827 | xfs_inode_t **ipp) | 840 | xfs_inode_t **ipp) |
| 828 | { | 841 | { |
| @@ -1481,7 +1494,7 @@ xfs_symlink( | |||
| 1481 | xfs_inode_t *dp, | 1494 | xfs_inode_t *dp, |
| 1482 | struct xfs_name *link_name, | 1495 | struct xfs_name *link_name, |
| 1483 | const char *target_path, | 1496 | const char *target_path, |
| 1484 | mode_t mode, | 1497 | umode_t mode, |
| 1485 | xfs_inode_t **ipp) | 1498 | xfs_inode_t **ipp) |
| 1486 | { | 1499 | { |
| 1487 | xfs_mount_t *mp = dp->i_mount; | 1500 | xfs_mount_t *mp = dp->i_mount; |
| @@ -1961,11 +1974,11 @@ xfs_zero_remaining_bytes( | |||
| 1961 | * since nothing can read beyond eof. The space will | 1974 | * since nothing can read beyond eof. The space will |
| 1962 | * be zeroed when the file is extended anyway. | 1975 | * be zeroed when the file is extended anyway. |
| 1963 | */ | 1976 | */ |
| 1964 | if (startoff >= ip->i_size) | 1977 | if (startoff >= XFS_ISIZE(ip)) |
| 1965 | return 0; | 1978 | return 0; |
| 1966 | 1979 | ||
| 1967 | if (endoff > ip->i_size) | 1980 | if (endoff > XFS_ISIZE(ip)) |
| 1968 | endoff = ip->i_size; | 1981 | endoff = XFS_ISIZE(ip); |
| 1969 | 1982 | ||
| 1970 | bp = xfs_buf_get_uncached(XFS_IS_REALTIME_INODE(ip) ? | 1983 | bp = xfs_buf_get_uncached(XFS_IS_REALTIME_INODE(ip) ? |
| 1971 | mp->m_rtdev_targp : mp->m_ddev_targp, | 1984 | mp->m_rtdev_targp : mp->m_ddev_targp, |
| @@ -2260,7 +2273,7 @@ xfs_change_file_space( | |||
| 2260 | bf->l_start += offset; | 2273 | bf->l_start += offset; |
| 2261 | break; | 2274 | break; |
| 2262 | case 2: /*SEEK_END*/ | 2275 | case 2: /*SEEK_END*/ |
| 2263 | bf->l_start += ip->i_size; | 2276 | bf->l_start += XFS_ISIZE(ip); |
| 2264 | break; | 2277 | break; |
| 2265 | default: | 2278 | default: |
| 2266 | return XFS_ERROR(EINVAL); | 2279 | return XFS_ERROR(EINVAL); |
| @@ -2277,7 +2290,7 @@ xfs_change_file_space( | |||
| 2277 | bf->l_whence = 0; | 2290 | bf->l_whence = 0; |
| 2278 | 2291 | ||
| 2279 | startoffset = bf->l_start; | 2292 | startoffset = bf->l_start; |
| 2280 | fsize = ip->i_size; | 2293 | fsize = XFS_ISIZE(ip); |
| 2281 | 2294 | ||
| 2282 | /* | 2295 | /* |
| 2283 | * XFS_IOC_RESVSP and XFS_IOC_UNRESVSP will reserve or unreserve | 2296 | * XFS_IOC_RESVSP and XFS_IOC_UNRESVSP will reserve or unreserve |
