aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r--fs/xfs/xfs_inode.c58
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 */
1424void 1427int
1425xfs_itruncate_start( 1428xfs_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