diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 61 |
1 files changed, 38 insertions, 23 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index df0d4572d70a..1d7f5a7e063e 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -404,9 +404,8 @@ xfs_iformat( | |||
404 | INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) + | 404 | INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) + |
405 | INT_GET(dip->di_core.di_anextents, ARCH_CONVERT) > | 405 | INT_GET(dip->di_core.di_anextents, ARCH_CONVERT) > |
406 | INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT))) { | 406 | INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT))) { |
407 | xfs_fs_cmn_err(CE_WARN, ip->i_mount, | 407 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
408 | "corrupt dinode %Lu, extent total = %d, nblocks = %Lu." | 408 | "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.", |
409 | " Unmount and run xfs_repair.", | ||
410 | (unsigned long long)ip->i_ino, | 409 | (unsigned long long)ip->i_ino, |
411 | (int)(INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) | 410 | (int)(INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) |
412 | + INT_GET(dip->di_core.di_anextents, ARCH_CONVERT)), | 411 | + INT_GET(dip->di_core.di_anextents, ARCH_CONVERT)), |
@@ -418,9 +417,8 @@ xfs_iformat( | |||
418 | } | 417 | } |
419 | 418 | ||
420 | if (unlikely(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT) > ip->i_mount->m_sb.sb_inodesize)) { | 419 | if (unlikely(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT) > ip->i_mount->m_sb.sb_inodesize)) { |
421 | xfs_fs_cmn_err(CE_WARN, ip->i_mount, | 420 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
422 | "corrupt dinode %Lu, forkoff = 0x%x." | 421 | "corrupt dinode %Lu, forkoff = 0x%x.", |
423 | " Unmount and run xfs_repair.", | ||
424 | (unsigned long long)ip->i_ino, | 422 | (unsigned long long)ip->i_ino, |
425 | (int)(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT))); | 423 | (int)(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT))); |
426 | XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW, | 424 | XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW, |
@@ -451,8 +449,9 @@ xfs_iformat( | |||
451 | * no local regular files yet | 449 | * no local regular files yet |
452 | */ | 450 | */ |
453 | if (unlikely((INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & S_IFMT) == S_IFREG)) { | 451 | if (unlikely((INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & S_IFMT) == S_IFREG)) { |
454 | xfs_fs_cmn_err(CE_WARN, ip->i_mount, | 452 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
455 | "corrupt inode (local format for regular file) %Lu. Unmount and run xfs_repair.", | 453 | "corrupt inode %Lu " |
454 | "(local format for regular file).", | ||
456 | (unsigned long long) ip->i_ino); | 455 | (unsigned long long) ip->i_ino); |
457 | XFS_CORRUPTION_ERROR("xfs_iformat(4)", | 456 | XFS_CORRUPTION_ERROR("xfs_iformat(4)", |
458 | XFS_ERRLEVEL_LOW, | 457 | XFS_ERRLEVEL_LOW, |
@@ -462,8 +461,9 @@ xfs_iformat( | |||
462 | 461 | ||
463 | di_size = INT_GET(dip->di_core.di_size, ARCH_CONVERT); | 462 | di_size = INT_GET(dip->di_core.di_size, ARCH_CONVERT); |
464 | if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) { | 463 | if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) { |
465 | xfs_fs_cmn_err(CE_WARN, ip->i_mount, | 464 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
466 | "corrupt inode %Lu (bad size %Ld for local inode). Unmount and run xfs_repair.", | 465 | "corrupt inode %Lu " |
466 | "(bad size %Ld for local inode).", | ||
467 | (unsigned long long) ip->i_ino, | 467 | (unsigned long long) ip->i_ino, |
468 | (long long) di_size); | 468 | (long long) di_size); |
469 | XFS_CORRUPTION_ERROR("xfs_iformat(5)", | 469 | XFS_CORRUPTION_ERROR("xfs_iformat(5)", |
@@ -551,8 +551,9 @@ xfs_iformat_local( | |||
551 | * kmem_alloc() or memcpy() below. | 551 | * kmem_alloc() or memcpy() below. |
552 | */ | 552 | */ |
553 | if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) { | 553 | if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) { |
554 | xfs_fs_cmn_err(CE_WARN, ip->i_mount, | 554 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
555 | "corrupt inode %Lu (bad size %d for local fork, size = %d). Unmount and run xfs_repair.", | 555 | "corrupt inode %Lu " |
556 | "(bad size %d for local fork, size = %d).", | ||
556 | (unsigned long long) ip->i_ino, size, | 557 | (unsigned long long) ip->i_ino, size, |
557 | XFS_DFORK_SIZE(dip, ip->i_mount, whichfork)); | 558 | XFS_DFORK_SIZE(dip, ip->i_mount, whichfork)); |
558 | XFS_CORRUPTION_ERROR("xfs_iformat_local", XFS_ERRLEVEL_LOW, | 559 | XFS_CORRUPTION_ERROR("xfs_iformat_local", XFS_ERRLEVEL_LOW, |
@@ -610,8 +611,8 @@ xfs_iformat_extents( | |||
610 | * kmem_alloc() or memcpy() below. | 611 | * kmem_alloc() or memcpy() below. |
611 | */ | 612 | */ |
612 | if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) { | 613 | if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) { |
613 | xfs_fs_cmn_err(CE_WARN, ip->i_mount, | 614 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
614 | "corrupt inode %Lu ((a)extents = %d). Unmount and run xfs_repair.", | 615 | "corrupt inode %Lu ((a)extents = %d).", |
615 | (unsigned long long) ip->i_ino, nex); | 616 | (unsigned long long) ip->i_ino, nex); |
616 | XFS_CORRUPTION_ERROR("xfs_iformat_extents(1)", XFS_ERRLEVEL_LOW, | 617 | XFS_CORRUPTION_ERROR("xfs_iformat_extents(1)", XFS_ERRLEVEL_LOW, |
617 | ip->i_mount, dip); | 618 | ip->i_mount, dip); |
@@ -692,8 +693,8 @@ xfs_iformat_btree( | |||
692 | || XFS_BMDR_SPACE_CALC(nrecs) > | 693 | || XFS_BMDR_SPACE_CALC(nrecs) > |
693 | XFS_DFORK_SIZE(dip, ip->i_mount, whichfork) | 694 | XFS_DFORK_SIZE(dip, ip->i_mount, whichfork) |
694 | || XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) { | 695 | || XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) { |
695 | xfs_fs_cmn_err(CE_WARN, ip->i_mount, | 696 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
696 | "corrupt inode %Lu (btree). Unmount and run xfs_repair.", | 697 | "corrupt inode %Lu (btree).", |
697 | (unsigned long long) ip->i_ino); | 698 | (unsigned long long) ip->i_ino); |
698 | XFS_ERROR_REPORT("xfs_iformat_btree", XFS_ERRLEVEL_LOW, | 699 | XFS_ERROR_REPORT("xfs_iformat_btree", XFS_ERRLEVEL_LOW, |
699 | ip->i_mount); | 700 | ip->i_mount); |
@@ -809,6 +810,10 @@ _xfs_dic2xflags( | |||
809 | flags |= XFS_XFLAG_PROJINHERIT; | 810 | flags |= XFS_XFLAG_PROJINHERIT; |
810 | if (di_flags & XFS_DIFLAG_NOSYMLINKS) | 811 | if (di_flags & XFS_DIFLAG_NOSYMLINKS) |
811 | flags |= XFS_XFLAG_NOSYMLINKS; | 812 | flags |= XFS_XFLAG_NOSYMLINKS; |
813 | if (di_flags & XFS_DIFLAG_EXTSIZE) | ||
814 | flags |= XFS_XFLAG_EXTSIZE; | ||
815 | if (di_flags & XFS_DIFLAG_EXTSZINHERIT) | ||
816 | flags |= XFS_XFLAG_EXTSZINHERIT; | ||
812 | } | 817 | } |
813 | 818 | ||
814 | return flags; | 819 | return flags; |
@@ -1192,11 +1197,19 @@ xfs_ialloc( | |||
1192 | if ((mode & S_IFMT) == S_IFDIR) { | 1197 | if ((mode & S_IFMT) == S_IFDIR) { |
1193 | if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) | 1198 | if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) |
1194 | di_flags |= XFS_DIFLAG_RTINHERIT; | 1199 | di_flags |= XFS_DIFLAG_RTINHERIT; |
1195 | } else { | 1200 | if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) { |
1201 | di_flags |= XFS_DIFLAG_EXTSZINHERIT; | ||
1202 | ip->i_d.di_extsize = pip->i_d.di_extsize; | ||
1203 | } | ||
1204 | } else if ((mode & S_IFMT) == S_IFREG) { | ||
1196 | if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) { | 1205 | if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) { |
1197 | di_flags |= XFS_DIFLAG_REALTIME; | 1206 | di_flags |= XFS_DIFLAG_REALTIME; |
1198 | ip->i_iocore.io_flags |= XFS_IOCORE_RT; | 1207 | ip->i_iocore.io_flags |= XFS_IOCORE_RT; |
1199 | } | 1208 | } |
1209 | if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) { | ||
1210 | di_flags |= XFS_DIFLAG_EXTSIZE; | ||
1211 | ip->i_d.di_extsize = pip->i_d.di_extsize; | ||
1212 | } | ||
1200 | } | 1213 | } |
1201 | if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) && | 1214 | if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) && |
1202 | xfs_inherit_noatime) | 1215 | xfs_inherit_noatime) |
@@ -1262,7 +1275,7 @@ xfs_isize_check( | |||
1262 | if ((ip->i_d.di_mode & S_IFMT) != S_IFREG) | 1275 | if ((ip->i_d.di_mode & S_IFMT) != S_IFREG) |
1263 | return; | 1276 | return; |
1264 | 1277 | ||
1265 | if ( ip->i_d.di_flags & XFS_DIFLAG_REALTIME ) | 1278 | if (ip->i_d.di_flags & (XFS_DIFLAG_REALTIME | XFS_DIFLAG_EXTSIZE)) |
1266 | return; | 1279 | return; |
1267 | 1280 | ||
1268 | nimaps = 2; | 1281 | nimaps = 2; |
@@ -1765,22 +1778,19 @@ xfs_igrow_start( | |||
1765 | xfs_fsize_t new_size, | 1778 | xfs_fsize_t new_size, |
1766 | cred_t *credp) | 1779 | cred_t *credp) |
1767 | { | 1780 | { |
1768 | xfs_fsize_t isize; | ||
1769 | int error; | 1781 | int error; |
1770 | 1782 | ||
1771 | ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0); | 1783 | ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0); |
1772 | ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0); | 1784 | ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0); |
1773 | ASSERT(new_size > ip->i_d.di_size); | 1785 | ASSERT(new_size > ip->i_d.di_size); |
1774 | 1786 | ||
1775 | error = 0; | ||
1776 | isize = ip->i_d.di_size; | ||
1777 | /* | 1787 | /* |
1778 | * Zero any pages that may have been created by | 1788 | * Zero any pages that may have been created by |
1779 | * xfs_write_file() beyond the end of the file | 1789 | * xfs_write_file() beyond the end of the file |
1780 | * and any blocks between the old and new file sizes. | 1790 | * and any blocks between the old and new file sizes. |
1781 | */ | 1791 | */ |
1782 | error = xfs_zero_eof(XFS_ITOV(ip), &ip->i_iocore, new_size, isize, | 1792 | error = xfs_zero_eof(XFS_ITOV(ip), &ip->i_iocore, new_size, |
1783 | new_size); | 1793 | ip->i_d.di_size, new_size); |
1784 | return error; | 1794 | return error; |
1785 | } | 1795 | } |
1786 | 1796 | ||
@@ -3355,6 +3365,11 @@ xfs_iflush_int( | |||
3355 | ip->i_update_core = 0; | 3365 | ip->i_update_core = 0; |
3356 | SYNCHRONIZE(); | 3366 | SYNCHRONIZE(); |
3357 | 3367 | ||
3368 | /* | ||
3369 | * Make sure to get the latest atime from the Linux inode. | ||
3370 | */ | ||
3371 | xfs_synchronize_atime(ip); | ||
3372 | |||
3358 | if (XFS_TEST_ERROR(INT_GET(dip->di_core.di_magic,ARCH_CONVERT) != XFS_DINODE_MAGIC, | 3373 | if (XFS_TEST_ERROR(INT_GET(dip->di_core.di_magic,ARCH_CONVERT) != XFS_DINODE_MAGIC, |
3359 | mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) { | 3374 | mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) { |
3360 | xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp, | 3375 | xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp, |