diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:59:33 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:59:33 -0400 |
| commit | 60c9b2746f589b0b809582b0471cf30ad3ae439f (patch) | |
| tree | deb0169acb7f7b5b5ef721650de1e0c6f139823c /fs/xfs/xfs_inode.c | |
| parent | 4750def52cb2c21732dda9aa1d43a07db37b0186 (diff) | |
| parent | f7c66ce3f70d8417de0cfb481ca4e5430382ec5d (diff) | |
Merge git://oss.sgi.com:8090/xfs/xfs-2.6
* git://oss.sgi.com:8090/xfs/xfs-2.6:
[XFS] Add lockdep support for XFS
[XFS] Fix race in xfs_write() b/w dmapi callout and direct I/O checks.
[XFS] Get rid of redundant "required" in msg.
[XFS] Export via a function xfs_buftarg_list for use by kdb/xfsidbg.
[XFS] Remove unused ilen variable and references.
[XFS] Fix to prevent the notorious 'NULL files' problem after a crash.
[XFS] Fix race condition in xfs_write().
[XFS] Fix uquota and oquota enforcement problems.
[XFS] propogate return codes from flush routines
[XFS] Fix quotaon syscall failures for group enforcement requests.
[XFS] Invalidate quotacheck when mounting without a quota type.
[XFS] reducing the number of random number functions.
[XFS] remove more misc. unused args
[XFS] the "aendp" arg to xfs_dir2_data_freescan is always NULL, remove it.
[XFS] The last argument "lsn" of xfs_trans_commit() is always called with
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 | ||
