diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 58 |
1 files changed, 44 insertions, 14 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 3da9829c19d5..3ca5d43b8345 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -442,6 +442,7 @@ xfs_iformat( | |||
442 | return XFS_ERROR(EFSCORRUPTED); | 442 | return XFS_ERROR(EFSCORRUPTED); |
443 | } | 443 | } |
444 | ip->i_d.di_size = 0; | 444 | ip->i_d.di_size = 0; |
445 | ip->i_size = 0; | ||
445 | ip->i_df.if_u2.if_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT); | 446 | ip->i_df.if_u2.if_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT); |
446 | break; | 447 | break; |
447 | 448 | ||
@@ -980,6 +981,7 @@ xfs_iread( | |||
980 | } | 981 | } |
981 | 982 | ||
982 | ip->i_delayed_blks = 0; | 983 | ip->i_delayed_blks = 0; |
984 | ip->i_size = ip->i_d.di_size; | ||
983 | 985 | ||
984 | /* | 986 | /* |
985 | * Mark the buffer containing the inode as something to keep | 987 | * Mark the buffer containing the inode as something to keep |
@@ -1170,6 +1172,7 @@ xfs_ialloc( | |||
1170 | } | 1172 | } |
1171 | 1173 | ||
1172 | ip->i_d.di_size = 0; | 1174 | ip->i_d.di_size = 0; |
1175 | ip->i_size = 0; | ||
1173 | ip->i_d.di_nextents = 0; | 1176 | ip->i_d.di_nextents = 0; |
1174 | ASSERT(ip->i_d.di_nblocks == 0); | 1177 | ASSERT(ip->i_d.di_nblocks == 0); |
1175 | xfs_ichgtime(ip, XFS_ICHGTIME_CHG|XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD); | 1178 | xfs_ichgtime(ip, XFS_ICHGTIME_CHG|XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD); |
@@ -1340,7 +1343,7 @@ xfs_file_last_byte( | |||
1340 | } else { | 1343 | } else { |
1341 | last_block = 0; | 1344 | last_block = 0; |
1342 | } | 1345 | } |
1343 | size_last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)ip->i_d.di_size); | 1346 | size_last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)ip->i_size); |
1344 | last_block = XFS_FILEOFF_MAX(last_block, size_last_block); | 1347 | last_block = XFS_FILEOFF_MAX(last_block, size_last_block); |
1345 | 1348 | ||
1346 | last_byte = XFS_FSB_TO_B(mp, last_block); | 1349 | last_byte = XFS_FSB_TO_B(mp, last_block); |
@@ -1421,7 +1424,7 @@ xfs_itrunc_trace( | |||
1421 | * must be called again with all the same restrictions as the initial | 1424 | * must be called again with all the same restrictions as the initial |
1422 | * call. | 1425 | * call. |
1423 | */ | 1426 | */ |
1424 | void | 1427 | int |
1425 | xfs_itruncate_start( | 1428 | xfs_itruncate_start( |
1426 | xfs_inode_t *ip, | 1429 | xfs_inode_t *ip, |
1427 | uint flags, | 1430 | uint flags, |
@@ -1431,9 +1434,10 @@ xfs_itruncate_start( | |||
1431 | xfs_off_t toss_start; | 1434 | xfs_off_t toss_start; |
1432 | xfs_mount_t *mp; | 1435 | xfs_mount_t *mp; |
1433 | bhv_vnode_t *vp; | 1436 | bhv_vnode_t *vp; |
1437 | int error = 0; | ||
1434 | 1438 | ||
1435 | ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0); | 1439 | ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0); |
1436 | ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size)); | 1440 | ASSERT((new_size == 0) || (new_size <= ip->i_size)); |
1437 | ASSERT((flags == XFS_ITRUNC_DEFINITE) || | 1441 | ASSERT((flags == XFS_ITRUNC_DEFINITE) || |
1438 | (flags == XFS_ITRUNC_MAYBE)); | 1442 | (flags == XFS_ITRUNC_MAYBE)); |
1439 | 1443 | ||
@@ -1468,7 +1472,7 @@ xfs_itruncate_start( | |||
1468 | * file size, so there is no way that the data extended | 1472 | * file size, so there is no way that the data extended |
1469 | * out there. | 1473 | * out there. |
1470 | */ | 1474 | */ |
1471 | return; | 1475 | return 0; |
1472 | } | 1476 | } |
1473 | last_byte = xfs_file_last_byte(ip); | 1477 | last_byte = xfs_file_last_byte(ip); |
1474 | xfs_itrunc_trace(XFS_ITRUNC_START, ip, flags, new_size, toss_start, | 1478 | xfs_itrunc_trace(XFS_ITRUNC_START, ip, flags, new_size, toss_start, |
@@ -1477,7 +1481,7 @@ xfs_itruncate_start( | |||
1477 | if (flags & XFS_ITRUNC_DEFINITE) { | 1481 | if (flags & XFS_ITRUNC_DEFINITE) { |
1478 | bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED); | 1482 | bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED); |
1479 | } else { | 1483 | } else { |
1480 | bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED); | 1484 | error = bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED); |
1481 | } | 1485 | } |
1482 | } | 1486 | } |
1483 | 1487 | ||
@@ -1486,6 +1490,7 @@ xfs_itruncate_start( | |||
1486 | ASSERT(VN_CACHED(vp) == 0); | 1490 | ASSERT(VN_CACHED(vp) == 0); |
1487 | } | 1491 | } |
1488 | #endif | 1492 | #endif |
1493 | return error; | ||
1489 | } | 1494 | } |
1490 | 1495 | ||
1491 | /* | 1496 | /* |
@@ -1556,7 +1561,7 @@ xfs_itruncate_finish( | |||
1556 | 1561 | ||
1557 | ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0); | 1562 | ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0); |
1558 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0); | 1563 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0); |
1559 | ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size)); | 1564 | ASSERT((new_size == 0) || (new_size <= ip->i_size)); |
1560 | ASSERT(*tp != NULL); | 1565 | ASSERT(*tp != NULL); |
1561 | ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); | 1566 | ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); |
1562 | ASSERT(ip->i_transp == *tp); | 1567 | ASSERT(ip->i_transp == *tp); |
@@ -1630,8 +1635,20 @@ xfs_itruncate_finish( | |||
1630 | */ | 1635 | */ |
1631 | if (fork == XFS_DATA_FORK) { | 1636 | if (fork == XFS_DATA_FORK) { |
1632 | if (ip->i_d.di_nextents > 0) { | 1637 | if (ip->i_d.di_nextents > 0) { |
1633 | ip->i_d.di_size = new_size; | 1638 | /* |
1634 | xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); | 1639 | * If we are not changing the file size then do |
1640 | * not update the on-disk file size - we may be | ||
1641 | * called from xfs_inactive_free_eofblocks(). If we | ||
1642 | * update the on-disk file size and then the system | ||
1643 | * crashes before the contents of the file are | ||
1644 | * flushed to disk then the files may be full of | ||
1645 | * holes (ie NULL files bug). | ||
1646 | */ | ||
1647 | if (ip->i_size != new_size) { | ||
1648 | ip->i_d.di_size = new_size; | ||
1649 | ip->i_size = new_size; | ||
1650 | xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); | ||
1651 | } | ||
1635 | } | 1652 | } |
1636 | } else if (sync) { | 1653 | } else if (sync) { |
1637 | ASSERT(!(mp->m_flags & XFS_MOUNT_WSYNC)); | 1654 | ASSERT(!(mp->m_flags & XFS_MOUNT_WSYNC)); |
@@ -1746,7 +1763,7 @@ xfs_itruncate_finish( | |||
1746 | xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); | 1763 | xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); |
1747 | } | 1764 | } |
1748 | ntp = xfs_trans_dup(ntp); | 1765 | ntp = xfs_trans_dup(ntp); |
1749 | (void) xfs_trans_commit(*tp, 0, NULL); | 1766 | (void) xfs_trans_commit(*tp, 0); |
1750 | *tp = ntp; | 1767 | *tp = ntp; |
1751 | error = xfs_trans_reserve(ntp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, | 1768 | error = xfs_trans_reserve(ntp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, |
1752 | XFS_TRANS_PERM_LOG_RES, | 1769 | XFS_TRANS_PERM_LOG_RES, |
@@ -1767,7 +1784,19 @@ xfs_itruncate_finish( | |||
1767 | */ | 1784 | */ |
1768 | if (fork == XFS_DATA_FORK) { | 1785 | if (fork == XFS_DATA_FORK) { |
1769 | xfs_isize_check(mp, ip, new_size); | 1786 | xfs_isize_check(mp, ip, new_size); |
1770 | ip->i_d.di_size = new_size; | 1787 | /* |
1788 | * If we are not changing the file size then do | ||
1789 | * not update the on-disk file size - we may be | ||
1790 | * called from xfs_inactive_free_eofblocks(). If we | ||
1791 | * update the on-disk file size and then the system | ||
1792 | * crashes before the contents of the file are | ||
1793 | * flushed to disk then the files may be full of | ||
1794 | * holes (ie NULL files bug). | ||
1795 | */ | ||
1796 | if (ip->i_size != new_size) { | ||
1797 | ip->i_d.di_size = new_size; | ||
1798 | ip->i_size = new_size; | ||
1799 | } | ||
1771 | } | 1800 | } |
1772 | xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); | 1801 | xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); |
1773 | ASSERT((new_size != 0) || | 1802 | ASSERT((new_size != 0) || |
@@ -1800,7 +1829,7 @@ xfs_igrow_start( | |||
1800 | 1829 | ||
1801 | ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0); | 1830 | ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0); |
1802 | ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0); | 1831 | ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0); |
1803 | ASSERT(new_size > ip->i_d.di_size); | 1832 | ASSERT(new_size > ip->i_size); |
1804 | 1833 | ||
1805 | /* | 1834 | /* |
1806 | * Zero any pages that may have been created by | 1835 | * Zero any pages that may have been created by |
@@ -1808,7 +1837,7 @@ xfs_igrow_start( | |||
1808 | * and any blocks between the old and new file sizes. | 1837 | * and any blocks between the old and new file sizes. |
1809 | */ | 1838 | */ |
1810 | error = xfs_zero_eof(XFS_ITOV(ip), &ip->i_iocore, new_size, | 1839 | error = xfs_zero_eof(XFS_ITOV(ip), &ip->i_iocore, new_size, |
1811 | ip->i_d.di_size); | 1840 | ip->i_size); |
1812 | return error; | 1841 | return error; |
1813 | } | 1842 | } |
1814 | 1843 | ||
@@ -1832,13 +1861,14 @@ xfs_igrow_finish( | |||
1832 | ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0); | 1861 | ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0); |
1833 | ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0); | 1862 | ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0); |
1834 | ASSERT(ip->i_transp == tp); | 1863 | ASSERT(ip->i_transp == tp); |
1835 | ASSERT(new_size > ip->i_d.di_size); | 1864 | ASSERT(new_size > ip->i_size); |
1836 | 1865 | ||
1837 | /* | 1866 | /* |
1838 | * Update the file size. Update the inode change timestamp | 1867 | * Update the file size. Update the inode change timestamp |
1839 | * if change_flag set. | 1868 | * if change_flag set. |
1840 | */ | 1869 | */ |
1841 | ip->i_d.di_size = new_size; | 1870 | ip->i_d.di_size = new_size; |
1871 | ip->i_size = new_size; | ||
1842 | if (change_flag) | 1872 | if (change_flag) |
1843 | xfs_ichgtime(ip, XFS_ICHGTIME_CHG); | 1873 | xfs_ichgtime(ip, XFS_ICHGTIME_CHG); |
1844 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 1874 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
@@ -2321,7 +2351,7 @@ xfs_ifree( | |||
2321 | ASSERT(ip->i_d.di_nlink == 0); | 2351 | ASSERT(ip->i_d.di_nlink == 0); |
2322 | ASSERT(ip->i_d.di_nextents == 0); | 2352 | ASSERT(ip->i_d.di_nextents == 0); |
2323 | ASSERT(ip->i_d.di_anextents == 0); | 2353 | ASSERT(ip->i_d.di_anextents == 0); |
2324 | ASSERT((ip->i_d.di_size == 0) || | 2354 | ASSERT((ip->i_d.di_size == 0 && ip->i_size == 0) || |
2325 | ((ip->i_d.di_mode & S_IFMT) != S_IFREG)); | 2355 | ((ip->i_d.di_mode & S_IFMT) != S_IFREG)); |
2326 | ASSERT(ip->i_d.di_nblocks == 0); | 2356 | ASSERT(ip->i_d.di_nblocks == 0); |
2327 | 2357 | ||