diff options
author | Dave Chinner <david@fromorbit.com> | 2014-08-03 23:55:27 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2014-08-03 23:55:27 -0400 |
commit | 645f9857213476407d8ed1b59619fdff7128d3e6 (patch) | |
tree | f48e76ffa8b4af8bfa0c64d54ff96d76b61f6f65 /fs/xfs | |
parent | b076d8720d793cde04b75b4941b8774e209649b4 (diff) | |
parent | 4ef897a27543b513351262881660147366c042a1 (diff) |
Merge branch 'xfs-misc-fixes-3.17-2' into for-next
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/libxfs/xfs_sb.c | 24 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap_util.c | 100 | ||||
-rw-r--r-- | fs/xfs/xfs_buf.c | 14 | ||||
-rw-r--r-- | fs/xfs/xfs_dquot.c | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_file.c | 10 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 10 | ||||
-rw-r--r-- | fs/xfs/xfs_ioctl.c | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_ioctl32.c | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_iops.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_linux.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_log.c | 8 | ||||
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 95 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_qm.c | 8 | ||||
-rw-r--r-- | fs/xfs/xfs_vnode.h | 46 |
16 files changed, 175 insertions, 161 deletions
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 6e93b5ef0a6b..ad525a5623a4 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c | |||
@@ -386,10 +386,11 @@ xfs_sb_quota_from_disk(struct xfs_sb *sbp) | |||
386 | } | 386 | } |
387 | } | 387 | } |
388 | 388 | ||
389 | void | 389 | static void |
390 | xfs_sb_from_disk( | 390 | __xfs_sb_from_disk( |
391 | struct xfs_sb *to, | 391 | struct xfs_sb *to, |
392 | xfs_dsb_t *from) | 392 | xfs_dsb_t *from, |
393 | bool convert_xquota) | ||
393 | { | 394 | { |
394 | to->sb_magicnum = be32_to_cpu(from->sb_magicnum); | 395 | to->sb_magicnum = be32_to_cpu(from->sb_magicnum); |
395 | to->sb_blocksize = be32_to_cpu(from->sb_blocksize); | 396 | to->sb_blocksize = be32_to_cpu(from->sb_blocksize); |
@@ -445,6 +446,17 @@ xfs_sb_from_disk( | |||
445 | to->sb_pad = 0; | 446 | to->sb_pad = 0; |
446 | to->sb_pquotino = be64_to_cpu(from->sb_pquotino); | 447 | to->sb_pquotino = be64_to_cpu(from->sb_pquotino); |
447 | to->sb_lsn = be64_to_cpu(from->sb_lsn); | 448 | to->sb_lsn = be64_to_cpu(from->sb_lsn); |
449 | /* Convert on-disk flags to in-memory flags? */ | ||
450 | if (convert_xquota) | ||
451 | xfs_sb_quota_from_disk(to); | ||
452 | } | ||
453 | |||
454 | void | ||
455 | xfs_sb_from_disk( | ||
456 | struct xfs_sb *to, | ||
457 | xfs_dsb_t *from) | ||
458 | { | ||
459 | __xfs_sb_from_disk(to, from, true); | ||
448 | } | 460 | } |
449 | 461 | ||
450 | static inline void | 462 | static inline void |
@@ -577,7 +589,11 @@ xfs_sb_verify( | |||
577 | struct xfs_mount *mp = bp->b_target->bt_mount; | 589 | struct xfs_mount *mp = bp->b_target->bt_mount; |
578 | struct xfs_sb sb; | 590 | struct xfs_sb sb; |
579 | 591 | ||
580 | xfs_sb_from_disk(&sb, XFS_BUF_TO_SBP(bp)); | 592 | /* |
593 | * Use call variant which doesn't convert quota flags from disk | ||
594 | * format, because xfs_mount_validate_sb checks the on-disk flags. | ||
595 | */ | ||
596 | __xfs_sb_from_disk(&sb, XFS_BUF_TO_SBP(bp), false); | ||
581 | 597 | ||
582 | /* | 598 | /* |
583 | * Only check the in progress field for the primary superblock as | 599 | * Only check the in progress field for the primary superblock as |
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index d32889af1777..2f1e30d39a35 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c | |||
@@ -809,7 +809,7 @@ xfs_can_free_eofblocks(struct xfs_inode *ip, bool force) | |||
809 | * have speculative prealloc/delalloc blocks to remove. | 809 | * have speculative prealloc/delalloc blocks to remove. |
810 | */ | 810 | */ |
811 | if (VFS_I(ip)->i_size == 0 && | 811 | if (VFS_I(ip)->i_size == 0 && |
812 | VN_CACHED(VFS_I(ip)) == 0 && | 812 | VFS_I(ip)->i_mapping->nrpages == 0 && |
813 | ip->i_delayed_blks == 0) | 813 | ip->i_delayed_blks == 0) |
814 | return false; | 814 | return false; |
815 | 815 | ||
@@ -1619,6 +1619,30 @@ xfs_swap_extents_check_format( | |||
1619 | } | 1619 | } |
1620 | 1620 | ||
1621 | int | 1621 | int |
1622 | xfs_swap_extent_flush( | ||
1623 | struct xfs_inode *ip) | ||
1624 | { | ||
1625 | int error; | ||
1626 | |||
1627 | error = filemap_write_and_wait(VFS_I(ip)->i_mapping); | ||
1628 | if (error) | ||
1629 | return error; | ||
1630 | truncate_pagecache_range(VFS_I(ip), 0, -1); | ||
1631 | |||
1632 | /* Verify O_DIRECT for ftmp */ | ||
1633 | if (VFS_I(ip)->i_mapping->nrpages) | ||
1634 | return -EINVAL; | ||
1635 | |||
1636 | /* | ||
1637 | * Don't try to swap extents on mmap()d files because we can't lock | ||
1638 | * out races against page faults safely. | ||
1639 | */ | ||
1640 | if (mapping_mapped(VFS_I(ip)->i_mapping)) | ||
1641 | return -EBUSY; | ||
1642 | return 0; | ||
1643 | } | ||
1644 | |||
1645 | int | ||
1622 | xfs_swap_extents( | 1646 | xfs_swap_extents( |
1623 | xfs_inode_t *ip, /* target inode */ | 1647 | xfs_inode_t *ip, /* target inode */ |
1624 | xfs_inode_t *tip, /* tmp inode */ | 1648 | xfs_inode_t *tip, /* tmp inode */ |
@@ -1633,6 +1657,7 @@ xfs_swap_extents( | |||
1633 | int aforkblks = 0; | 1657 | int aforkblks = 0; |
1634 | int taforkblks = 0; | 1658 | int taforkblks = 0; |
1635 | __uint64_t tmp; | 1659 | __uint64_t tmp; |
1660 | int lock_flags; | ||
1636 | 1661 | ||
1637 | tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); | 1662 | tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); |
1638 | if (!tempifp) { | 1663 | if (!tempifp) { |
@@ -1641,13 +1666,13 @@ xfs_swap_extents( | |||
1641 | } | 1666 | } |
1642 | 1667 | ||
1643 | /* | 1668 | /* |
1644 | * we have to do two separate lock calls here to keep lockdep | 1669 | * Lock up the inodes against other IO and truncate to begin with. |
1645 | * happy. If we try to get all the locks in one call, lock will | 1670 | * Then we can ensure the inodes are flushed and have no page cache |
1646 | * report false positives when we drop the ILOCK and regain them | 1671 | * safely. Once we have done this we can take the ilocks and do the rest |
1647 | * below. | 1672 | * of the checks. |
1648 | */ | 1673 | */ |
1674 | lock_flags = XFS_IOLOCK_EXCL; | ||
1649 | xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL); | 1675 | xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL); |
1650 | xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL); | ||
1651 | 1676 | ||
1652 | /* Verify that both files have the same format */ | 1677 | /* Verify that both files have the same format */ |
1653 | if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) { | 1678 | if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) { |
@@ -1661,23 +1686,28 @@ xfs_swap_extents( | |||
1661 | goto out_unlock; | 1686 | goto out_unlock; |
1662 | } | 1687 | } |
1663 | 1688 | ||
1664 | error = filemap_write_and_wait(VFS_I(tip)->i_mapping); | 1689 | error = xfs_swap_extent_flush(ip); |
1690 | if (error) | ||
1691 | goto out_unlock; | ||
1692 | error = xfs_swap_extent_flush(tip); | ||
1665 | if (error) | 1693 | if (error) |
1666 | goto out_unlock; | 1694 | goto out_unlock; |
1667 | truncate_pagecache_range(VFS_I(tip), 0, -1); | ||
1668 | 1695 | ||
1669 | /* Verify O_DIRECT for ftmp */ | 1696 | tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT); |
1670 | if (VN_CACHED(VFS_I(tip)) != 0) { | 1697 | error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0); |
1671 | error = -EINVAL; | 1698 | if (error) { |
1699 | xfs_trans_cancel(tp, 0); | ||
1672 | goto out_unlock; | 1700 | goto out_unlock; |
1673 | } | 1701 | } |
1702 | xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL); | ||
1703 | lock_flags |= XFS_ILOCK_EXCL; | ||
1674 | 1704 | ||
1675 | /* Verify all data are being swapped */ | 1705 | /* Verify all data are being swapped */ |
1676 | if (sxp->sx_offset != 0 || | 1706 | if (sxp->sx_offset != 0 || |
1677 | sxp->sx_length != ip->i_d.di_size || | 1707 | sxp->sx_length != ip->i_d.di_size || |
1678 | sxp->sx_length != tip->i_d.di_size) { | 1708 | sxp->sx_length != tip->i_d.di_size) { |
1679 | error = -EFAULT; | 1709 | error = -EFAULT; |
1680 | goto out_unlock; | 1710 | goto out_trans_cancel; |
1681 | } | 1711 | } |
1682 | 1712 | ||
1683 | trace_xfs_swap_extent_before(ip, 0); | 1713 | trace_xfs_swap_extent_before(ip, 0); |
@@ -1689,7 +1719,7 @@ xfs_swap_extents( | |||
1689 | xfs_notice(mp, | 1719 | xfs_notice(mp, |
1690 | "%s: inode 0x%llx format is incompatible for exchanging.", | 1720 | "%s: inode 0x%llx format is incompatible for exchanging.", |
1691 | __func__, ip->i_ino); | 1721 | __func__, ip->i_ino); |
1692 | goto out_unlock; | 1722 | goto out_trans_cancel; |
1693 | } | 1723 | } |
1694 | 1724 | ||
1695 | /* | 1725 | /* |
@@ -1704,42 +1734,8 @@ xfs_swap_extents( | |||
1704 | (sbp->bs_mtime.tv_sec != VFS_I(ip)->i_mtime.tv_sec) || | 1734 | (sbp->bs_mtime.tv_sec != VFS_I(ip)->i_mtime.tv_sec) || |
1705 | (sbp->bs_mtime.tv_nsec != VFS_I(ip)->i_mtime.tv_nsec)) { | 1735 | (sbp->bs_mtime.tv_nsec != VFS_I(ip)->i_mtime.tv_nsec)) { |
1706 | error = -EBUSY; | 1736 | error = -EBUSY; |
1707 | goto out_unlock; | 1737 | goto out_trans_cancel; |
1708 | } | ||
1709 | |||
1710 | /* We need to fail if the file is memory mapped. Once we have tossed | ||
1711 | * all existing pages, the page fault will have no option | ||
1712 | * but to go to the filesystem for pages. By making the page fault call | ||
1713 | * vop_read (or write in the case of autogrow) they block on the iolock | ||
1714 | * until we have switched the extents. | ||
1715 | */ | ||
1716 | if (VN_MAPPED(VFS_I(ip))) { | ||
1717 | error = -EBUSY; | ||
1718 | goto out_unlock; | ||
1719 | } | ||
1720 | |||
1721 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
1722 | xfs_iunlock(tip, XFS_ILOCK_EXCL); | ||
1723 | |||
1724 | /* | ||
1725 | * There is a race condition here since we gave up the | ||
1726 | * ilock. However, the data fork will not change since | ||
1727 | * we have the iolock (locked for truncation too) so we | ||
1728 | * are safe. We don't really care if non-io related | ||
1729 | * fields change. | ||
1730 | */ | ||
1731 | truncate_pagecache_range(VFS_I(ip), 0, -1); | ||
1732 | |||
1733 | tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT); | ||
1734 | error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0); | ||
1735 | if (error) { | ||
1736 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
1737 | xfs_iunlock(tip, XFS_IOLOCK_EXCL); | ||
1738 | xfs_trans_cancel(tp, 0); | ||
1739 | goto out; | ||
1740 | } | 1738 | } |
1741 | xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL); | ||
1742 | |||
1743 | /* | 1739 | /* |
1744 | * Count the number of extended attribute blocks | 1740 | * Count the number of extended attribute blocks |
1745 | */ | 1741 | */ |
@@ -1757,8 +1753,8 @@ xfs_swap_extents( | |||
1757 | goto out_trans_cancel; | 1753 | goto out_trans_cancel; |
1758 | } | 1754 | } |
1759 | 1755 | ||
1760 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | 1756 | xfs_trans_ijoin(tp, ip, lock_flags); |
1761 | xfs_trans_ijoin(tp, tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | 1757 | xfs_trans_ijoin(tp, tip, lock_flags); |
1762 | 1758 | ||
1763 | /* | 1759 | /* |
1764 | * Before we've swapped the forks, lets set the owners of the forks | 1760 | * Before we've swapped the forks, lets set the owners of the forks |
@@ -1887,8 +1883,8 @@ out: | |||
1887 | return error; | 1883 | return error; |
1888 | 1884 | ||
1889 | out_unlock: | 1885 | out_unlock: |
1890 | xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | 1886 | xfs_iunlock(ip, lock_flags); |
1891 | xfs_iunlock(tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | 1887 | xfs_iunlock(tip, lock_flags); |
1892 | goto out; | 1888 | goto out; |
1893 | 1889 | ||
1894 | out_trans_cancel: | 1890 | out_trans_cancel: |
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index a6dc83e70ece..cd7b8ca9b064 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -1330,6 +1330,20 @@ _xfs_buf_ioapply( | |||
1330 | SHUTDOWN_CORRUPT_INCORE); | 1330 | SHUTDOWN_CORRUPT_INCORE); |
1331 | return; | 1331 | return; |
1332 | } | 1332 | } |
1333 | } else if (bp->b_bn != XFS_BUF_DADDR_NULL) { | ||
1334 | struct xfs_mount *mp = bp->b_target->bt_mount; | ||
1335 | |||
1336 | /* | ||
1337 | * non-crc filesystems don't attach verifiers during | ||
1338 | * log recovery, so don't warn for such filesystems. | ||
1339 | */ | ||
1340 | if (xfs_sb_version_hascrc(&mp->m_sb)) { | ||
1341 | xfs_warn(mp, | ||
1342 | "%s: no ops on block 0x%llx/0x%x", | ||
1343 | __func__, bp->b_bn, bp->b_length); | ||
1344 | xfs_hex_dump(bp->b_addr, 64); | ||
1345 | dump_stack(); | ||
1346 | } | ||
1333 | } | 1347 | } |
1334 | } else if (bp->b_flags & XBF_READ_AHEAD) { | 1348 | } else if (bp->b_flags & XBF_READ_AHEAD) { |
1335 | rw = READA; | 1349 | rw = READA; |
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 8a44a79f49af..63c2de49f61d 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c | |||
@@ -974,7 +974,8 @@ xfs_qm_dqflush( | |||
974 | * Get the buffer containing the on-disk dquot | 974 | * Get the buffer containing the on-disk dquot |
975 | */ | 975 | */ |
976 | error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dqp->q_blkno, | 976 | error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dqp->q_blkno, |
977 | mp->m_quotainfo->qi_dqchunklen, 0, &bp, NULL); | 977 | mp->m_quotainfo->qi_dqchunklen, 0, &bp, |
978 | &xfs_dquot_buf_ops); | ||
978 | if (error) | 979 | if (error) |
979 | goto out_unlock; | 980 | goto out_unlock; |
980 | 981 | ||
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index fcf91a22f5d8..076b1708d134 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -247,11 +247,11 @@ xfs_file_read_iter( | |||
247 | XFS_STATS_INC(xs_read_calls); | 247 | XFS_STATS_INC(xs_read_calls); |
248 | 248 | ||
249 | if (unlikely(file->f_flags & O_DIRECT)) | 249 | if (unlikely(file->f_flags & O_DIRECT)) |
250 | ioflags |= IO_ISDIRECT; | 250 | ioflags |= XFS_IO_ISDIRECT; |
251 | if (file->f_mode & FMODE_NOCMTIME) | 251 | if (file->f_mode & FMODE_NOCMTIME) |
252 | ioflags |= IO_INVIS; | 252 | ioflags |= XFS_IO_INVIS; |
253 | 253 | ||
254 | if (unlikely(ioflags & IO_ISDIRECT)) { | 254 | if (unlikely(ioflags & XFS_IO_ISDIRECT)) { |
255 | xfs_buftarg_t *target = | 255 | xfs_buftarg_t *target = |
256 | XFS_IS_REALTIME_INODE(ip) ? | 256 | XFS_IS_REALTIME_INODE(ip) ? |
257 | mp->m_rtdev_targp : mp->m_ddev_targp; | 257 | mp->m_rtdev_targp : mp->m_ddev_targp; |
@@ -284,7 +284,7 @@ xfs_file_read_iter( | |||
284 | * proceeed concurrently without serialisation. | 284 | * proceeed concurrently without serialisation. |
285 | */ | 285 | */ |
286 | xfs_rw_ilock(ip, XFS_IOLOCK_SHARED); | 286 | xfs_rw_ilock(ip, XFS_IOLOCK_SHARED); |
287 | if ((ioflags & IO_ISDIRECT) && inode->i_mapping->nrpages) { | 287 | if ((ioflags & XFS_IO_ISDIRECT) && inode->i_mapping->nrpages) { |
288 | xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); | 288 | xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); |
289 | xfs_rw_ilock(ip, XFS_IOLOCK_EXCL); | 289 | xfs_rw_ilock(ip, XFS_IOLOCK_EXCL); |
290 | 290 | ||
@@ -326,7 +326,7 @@ xfs_file_splice_read( | |||
326 | XFS_STATS_INC(xs_read_calls); | 326 | XFS_STATS_INC(xs_read_calls); |
327 | 327 | ||
328 | if (infilp->f_mode & FMODE_NOCMTIME) | 328 | if (infilp->f_mode & FMODE_NOCMTIME) |
329 | ioflags |= IO_INVIS; | 329 | ioflags |= XFS_IO_INVIS; |
330 | 330 | ||
331 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | 331 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
332 | return -EIO; | 332 | return -EIO; |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 1a5e068bc420..fea3c92fb3f0 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -1635,7 +1635,7 @@ xfs_release( | |||
1635 | truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED); | 1635 | truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED); |
1636 | if (truncated) { | 1636 | if (truncated) { |
1637 | xfs_iflags_clear(ip, XFS_IDIRTY_RELEASE); | 1637 | xfs_iflags_clear(ip, XFS_IDIRTY_RELEASE); |
1638 | if (VN_DIRTY(VFS_I(ip)) && ip->i_delayed_blks > 0) { | 1638 | if (ip->i_delayed_blks > 0) { |
1639 | error = filemap_flush(VFS_I(ip)->i_mapping); | 1639 | error = filemap_flush(VFS_I(ip)->i_mapping); |
1640 | if (error) | 1640 | if (error) |
1641 | return error; | 1641 | return error; |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index f72bffa67266..c10e3fadd9af 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -398,4 +398,14 @@ do { \ | |||
398 | 398 | ||
399 | extern struct kmem_zone *xfs_inode_zone; | 399 | extern struct kmem_zone *xfs_inode_zone; |
400 | 400 | ||
401 | /* | ||
402 | * Flags for read/write calls | ||
403 | */ | ||
404 | #define XFS_IO_ISDIRECT 0x00001 /* bypass page cache */ | ||
405 | #define XFS_IO_INVIS 0x00002 /* don't update inode timestamps */ | ||
406 | |||
407 | #define XFS_IO_FLAGS \ | ||
408 | { XFS_IO_ISDIRECT, "DIRECT" }, \ | ||
409 | { XFS_IO_INVIS, "INVIS"} | ||
410 | |||
401 | #endif /* __XFS_INODE_H__ */ | 411 | #endif /* __XFS_INODE_H__ */ |
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 494237ed4a65..3799695b9249 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c | |||
@@ -736,7 +736,7 @@ xfs_ioc_space( | |||
736 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 736 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
737 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | 737 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); |
738 | 738 | ||
739 | if (!(ioflags & IO_INVIS)) { | 739 | if (!(ioflags & XFS_IO_INVIS)) { |
740 | ip->i_d.di_mode &= ~S_ISUID; | 740 | ip->i_d.di_mode &= ~S_ISUID; |
741 | if (ip->i_d.di_mode & S_IXGRP) | 741 | if (ip->i_d.di_mode & S_IXGRP) |
742 | ip->i_d.di_mode &= ~S_ISGID; | 742 | ip->i_d.di_mode &= ~S_ISGID; |
@@ -1376,7 +1376,7 @@ xfs_ioc_getbmap( | |||
1376 | return -EINVAL; | 1376 | return -EINVAL; |
1377 | 1377 | ||
1378 | bmx.bmv_iflags = (cmd == XFS_IOC_GETBMAPA ? BMV_IF_ATTRFORK : 0); | 1378 | bmx.bmv_iflags = (cmd == XFS_IOC_GETBMAPA ? BMV_IF_ATTRFORK : 0); |
1379 | if (ioflags & IO_INVIS) | 1379 | if (ioflags & XFS_IO_INVIS) |
1380 | bmx.bmv_iflags |= BMV_IF_NO_DMAPI_READ; | 1380 | bmx.bmv_iflags |= BMV_IF_NO_DMAPI_READ; |
1381 | 1381 | ||
1382 | error = xfs_getbmap(ip, &bmx, xfs_getbmap_format, | 1382 | error = xfs_getbmap(ip, &bmx, xfs_getbmap_format, |
@@ -1520,7 +1520,7 @@ xfs_file_ioctl( | |||
1520 | int error; | 1520 | int error; |
1521 | 1521 | ||
1522 | if (filp->f_mode & FMODE_NOCMTIME) | 1522 | if (filp->f_mode & FMODE_NOCMTIME) |
1523 | ioflags |= IO_INVIS; | 1523 | ioflags |= XFS_IO_INVIS; |
1524 | 1524 | ||
1525 | trace_xfs_file_ioctl(ip); | 1525 | trace_xfs_file_ioctl(ip); |
1526 | 1526 | ||
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c index cf63418bf05f..a554646ff141 100644 --- a/fs/xfs/xfs_ioctl32.c +++ b/fs/xfs/xfs_ioctl32.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include "xfs_sb.h" | 28 | #include "xfs_sb.h" |
29 | #include "xfs_ag.h" | 29 | #include "xfs_ag.h" |
30 | #include "xfs_mount.h" | 30 | #include "xfs_mount.h" |
31 | #include "xfs_vnode.h" | ||
32 | #include "xfs_inode.h" | 31 | #include "xfs_inode.h" |
33 | #include "xfs_itable.h" | 32 | #include "xfs_itable.h" |
34 | #include "xfs_error.h" | 33 | #include "xfs_error.h" |
@@ -537,7 +536,7 @@ xfs_file_compat_ioctl( | |||
537 | int error; | 536 | int error; |
538 | 537 | ||
539 | if (filp->f_mode & FMODE_NOCMTIME) | 538 | if (filp->f_mode & FMODE_NOCMTIME) |
540 | ioflags |= IO_INVIS; | 539 | ioflags |= XFS_IO_INVIS; |
541 | 540 | ||
542 | trace_xfs_file_compat_ioctl(ip); | 541 | trace_xfs_file_compat_ioctl(ip); |
543 | 542 | ||
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index d75621ae3e36..72129493e9d3 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
@@ -1055,12 +1055,12 @@ xfs_vn_fiemap( | |||
1055 | return error; | 1055 | return error; |
1056 | 1056 | ||
1057 | /* Set up bmap header for xfs internal routine */ | 1057 | /* Set up bmap header for xfs internal routine */ |
1058 | bm.bmv_offset = BTOBB(start); | 1058 | bm.bmv_offset = BTOBBT(start); |
1059 | /* Special case for whole file */ | 1059 | /* Special case for whole file */ |
1060 | if (length == FIEMAP_MAX_OFFSET) | 1060 | if (length == FIEMAP_MAX_OFFSET) |
1061 | bm.bmv_length = -1LL; | 1061 | bm.bmv_length = -1LL; |
1062 | else | 1062 | else |
1063 | bm.bmv_length = BTOBB(length); | 1063 | bm.bmv_length = BTOBB(start + length) - bm.bmv_offset; |
1064 | 1064 | ||
1065 | /* We add one because in getbmap world count includes the header */ | 1065 | /* We add one because in getbmap world count includes the header */ |
1066 | bm.bmv_count = !fieinfo->fi_extents_max ? MAXEXTNUM : | 1066 | bm.bmv_count = !fieinfo->fi_extents_max ? MAXEXTNUM : |
diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h index d3ef6de475bb..d10dc8f397c9 100644 --- a/fs/xfs/xfs_linux.h +++ b/fs/xfs/xfs_linux.h | |||
@@ -101,7 +101,7 @@ typedef __uint64_t __psunsigned_t; | |||
101 | #include <asm/byteorder.h> | 101 | #include <asm/byteorder.h> |
102 | #include <asm/unaligned.h> | 102 | #include <asm/unaligned.h> |
103 | 103 | ||
104 | #include "xfs_vnode.h" | 104 | #include "xfs_fs.h" |
105 | #include "xfs_stats.h" | 105 | #include "xfs_stats.h" |
106 | #include "xfs_sysctl.h" | 106 | #include "xfs_sysctl.h" |
107 | #include "xfs_iops.h" | 107 | #include "xfs_iops.h" |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 149a4a575a09..ca4fd5bd8522 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -1378,8 +1378,14 @@ xlog_alloc_log( | |||
1378 | 1378 | ||
1379 | xlog_get_iclog_buffer_size(mp, log); | 1379 | xlog_get_iclog_buffer_size(mp, log); |
1380 | 1380 | ||
1381 | /* | ||
1382 | * Use a NULL block for the extra log buffer used during splits so that | ||
1383 | * it will trigger errors if we ever try to do IO on it without first | ||
1384 | * having set it up properly. | ||
1385 | */ | ||
1381 | error = -ENOMEM; | 1386 | error = -ENOMEM; |
1382 | bp = xfs_buf_alloc(mp->m_logdev_targp, 0, BTOBB(log->l_iclog_size), 0); | 1387 | bp = xfs_buf_alloc(mp->m_logdev_targp, XFS_BUF_DADDR_NULL, |
1388 | BTOBB(log->l_iclog_size), 0); | ||
1383 | if (!bp) | 1389 | if (!bp) |
1384 | goto out_free_log; | 1390 | goto out_free_log; |
1385 | 1391 | ||
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index fbc2362d13e3..1fd5787add99 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -2126,6 +2126,17 @@ xlog_recover_validate_buf_type( | |||
2126 | __uint16_t magic16; | 2126 | __uint16_t magic16; |
2127 | __uint16_t magicda; | 2127 | __uint16_t magicda; |
2128 | 2128 | ||
2129 | /* | ||
2130 | * We can only do post recovery validation on items on CRC enabled | ||
2131 | * fielsystems as we need to know when the buffer was written to be able | ||
2132 | * to determine if we should have replayed the item. If we replay old | ||
2133 | * metadata over a newer buffer, then it will enter a temporarily | ||
2134 | * inconsistent state resulting in verification failures. Hence for now | ||
2135 | * just avoid the verification stage for non-crc filesystems | ||
2136 | */ | ||
2137 | if (!xfs_sb_version_hascrc(&mp->m_sb)) | ||
2138 | return; | ||
2139 | |||
2129 | magic32 = be32_to_cpu(*(__be32 *)bp->b_addr); | 2140 | magic32 = be32_to_cpu(*(__be32 *)bp->b_addr); |
2130 | magic16 = be16_to_cpu(*(__be16*)bp->b_addr); | 2141 | magic16 = be16_to_cpu(*(__be16*)bp->b_addr); |
2131 | magicda = be16_to_cpu(info->magic); | 2142 | magicda = be16_to_cpu(info->magic); |
@@ -2163,8 +2174,6 @@ xlog_recover_validate_buf_type( | |||
2163 | bp->b_ops = &xfs_agf_buf_ops; | 2174 | bp->b_ops = &xfs_agf_buf_ops; |
2164 | break; | 2175 | break; |
2165 | case XFS_BLFT_AGFL_BUF: | 2176 | case XFS_BLFT_AGFL_BUF: |
2166 | if (!xfs_sb_version_hascrc(&mp->m_sb)) | ||
2167 | break; | ||
2168 | if (magic32 != XFS_AGFL_MAGIC) { | 2177 | if (magic32 != XFS_AGFL_MAGIC) { |
2169 | xfs_warn(mp, "Bad AGFL block magic!"); | 2178 | xfs_warn(mp, "Bad AGFL block magic!"); |
2170 | ASSERT(0); | 2179 | ASSERT(0); |
@@ -2197,10 +2206,6 @@ xlog_recover_validate_buf_type( | |||
2197 | #endif | 2206 | #endif |
2198 | break; | 2207 | break; |
2199 | case XFS_BLFT_DINO_BUF: | 2208 | case XFS_BLFT_DINO_BUF: |
2200 | /* | ||
2201 | * we get here with inode allocation buffers, not buffers that | ||
2202 | * track unlinked list changes. | ||
2203 | */ | ||
2204 | if (magic16 != XFS_DINODE_MAGIC) { | 2209 | if (magic16 != XFS_DINODE_MAGIC) { |
2205 | xfs_warn(mp, "Bad INODE block magic!"); | 2210 | xfs_warn(mp, "Bad INODE block magic!"); |
2206 | ASSERT(0); | 2211 | ASSERT(0); |
@@ -2280,8 +2285,6 @@ xlog_recover_validate_buf_type( | |||
2280 | bp->b_ops = &xfs_attr3_leaf_buf_ops; | 2285 | bp->b_ops = &xfs_attr3_leaf_buf_ops; |
2281 | break; | 2286 | break; |
2282 | case XFS_BLFT_ATTR_RMT_BUF: | 2287 | case XFS_BLFT_ATTR_RMT_BUF: |
2283 | if (!xfs_sb_version_hascrc(&mp->m_sb)) | ||
2284 | break; | ||
2285 | if (magic32 != XFS_ATTR3_RMT_MAGIC) { | 2288 | if (magic32 != XFS_ATTR3_RMT_MAGIC) { |
2286 | xfs_warn(mp, "Bad attr remote magic!"); | 2289 | xfs_warn(mp, "Bad attr remote magic!"); |
2287 | ASSERT(0); | 2290 | ASSERT(0); |
@@ -2388,16 +2391,7 @@ xlog_recover_do_reg_buffer( | |||
2388 | /* Shouldn't be any more regions */ | 2391 | /* Shouldn't be any more regions */ |
2389 | ASSERT(i == item->ri_total); | 2392 | ASSERT(i == item->ri_total); |
2390 | 2393 | ||
2391 | /* | 2394 | xlog_recover_validate_buf_type(mp, bp, buf_f); |
2392 | * We can only do post recovery validation on items on CRC enabled | ||
2393 | * fielsystems as we need to know when the buffer was written to be able | ||
2394 | * to determine if we should have replayed the item. If we replay old | ||
2395 | * metadata over a newer buffer, then it will enter a temporarily | ||
2396 | * inconsistent state resulting in verification failures. Hence for now | ||
2397 | * just avoid the verification stage for non-crc filesystems | ||
2398 | */ | ||
2399 | if (xfs_sb_version_hascrc(&mp->m_sb)) | ||
2400 | xlog_recover_validate_buf_type(mp, bp, buf_f); | ||
2401 | } | 2395 | } |
2402 | 2396 | ||
2403 | /* | 2397 | /* |
@@ -2405,8 +2399,11 @@ xlog_recover_do_reg_buffer( | |||
2405 | * Simple algorithm: if we have found a QUOTAOFF log item of the same type | 2399 | * Simple algorithm: if we have found a QUOTAOFF log item of the same type |
2406 | * (ie. USR or GRP), then just toss this buffer away; don't recover it. | 2400 | * (ie. USR or GRP), then just toss this buffer away; don't recover it. |
2407 | * Else, treat it as a regular buffer and do recovery. | 2401 | * Else, treat it as a regular buffer and do recovery. |
2402 | * | ||
2403 | * Return false if the buffer was tossed and true if we recovered the buffer to | ||
2404 | * indicate to the caller if the buffer needs writing. | ||
2408 | */ | 2405 | */ |
2409 | STATIC void | 2406 | STATIC bool |
2410 | xlog_recover_do_dquot_buffer( | 2407 | xlog_recover_do_dquot_buffer( |
2411 | struct xfs_mount *mp, | 2408 | struct xfs_mount *mp, |
2412 | struct xlog *log, | 2409 | struct xlog *log, |
@@ -2421,9 +2418,8 @@ xlog_recover_do_dquot_buffer( | |||
2421 | /* | 2418 | /* |
2422 | * Filesystems are required to send in quota flags at mount time. | 2419 | * Filesystems are required to send in quota flags at mount time. |
2423 | */ | 2420 | */ |
2424 | if (mp->m_qflags == 0) { | 2421 | if (!mp->m_qflags) |
2425 | return; | 2422 | return false; |
2426 | } | ||
2427 | 2423 | ||
2428 | type = 0; | 2424 | type = 0; |
2429 | if (buf_f->blf_flags & XFS_BLF_UDQUOT_BUF) | 2425 | if (buf_f->blf_flags & XFS_BLF_UDQUOT_BUF) |
@@ -2436,9 +2432,10 @@ xlog_recover_do_dquot_buffer( | |||
2436 | * This type of quotas was turned off, so ignore this buffer | 2432 | * This type of quotas was turned off, so ignore this buffer |
2437 | */ | 2433 | */ |
2438 | if (log->l_quotaoffs_flag & type) | 2434 | if (log->l_quotaoffs_flag & type) |
2439 | return; | 2435 | return false; |
2440 | 2436 | ||
2441 | xlog_recover_do_reg_buffer(mp, item, bp, buf_f); | 2437 | xlog_recover_do_reg_buffer(mp, item, bp, buf_f); |
2438 | return true; | ||
2442 | } | 2439 | } |
2443 | 2440 | ||
2444 | /* | 2441 | /* |
@@ -2505,23 +2502,44 @@ xlog_recover_buffer_pass2( | |||
2505 | } | 2502 | } |
2506 | 2503 | ||
2507 | /* | 2504 | /* |
2508 | * recover the buffer only if we get an LSN from it and it's less than | 2505 | * Recover the buffer only if we get an LSN from it and it's less than |
2509 | * the lsn of the transaction we are replaying. | 2506 | * the lsn of the transaction we are replaying. |
2507 | * | ||
2508 | * Note that we have to be extremely careful of readahead here. | ||
2509 | * Readahead does not attach verfiers to the buffers so if we don't | ||
2510 | * actually do any replay after readahead because of the LSN we found | ||
2511 | * in the buffer if more recent than that current transaction then we | ||
2512 | * need to attach the verifier directly. Failure to do so can lead to | ||
2513 | * future recovery actions (e.g. EFI and unlinked list recovery) can | ||
2514 | * operate on the buffers and they won't get the verifier attached. This | ||
2515 | * can lead to blocks on disk having the correct content but a stale | ||
2516 | * CRC. | ||
2517 | * | ||
2518 | * It is safe to assume these clean buffers are currently up to date. | ||
2519 | * If the buffer is dirtied by a later transaction being replayed, then | ||
2520 | * the verifier will be reset to match whatever recover turns that | ||
2521 | * buffer into. | ||
2510 | */ | 2522 | */ |
2511 | lsn = xlog_recover_get_buf_lsn(mp, bp); | 2523 | lsn = xlog_recover_get_buf_lsn(mp, bp); |
2512 | if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0) | 2524 | if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0) { |
2525 | xlog_recover_validate_buf_type(mp, bp, buf_f); | ||
2513 | goto out_release; | 2526 | goto out_release; |
2527 | } | ||
2514 | 2528 | ||
2515 | if (buf_f->blf_flags & XFS_BLF_INODE_BUF) { | 2529 | if (buf_f->blf_flags & XFS_BLF_INODE_BUF) { |
2516 | error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f); | 2530 | error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f); |
2531 | if (error) | ||
2532 | goto out_release; | ||
2517 | } else if (buf_f->blf_flags & | 2533 | } else if (buf_f->blf_flags & |
2518 | (XFS_BLF_UDQUOT_BUF|XFS_BLF_PDQUOT_BUF|XFS_BLF_GDQUOT_BUF)) { | 2534 | (XFS_BLF_UDQUOT_BUF|XFS_BLF_PDQUOT_BUF|XFS_BLF_GDQUOT_BUF)) { |
2519 | xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f); | 2535 | bool dirty; |
2536 | |||
2537 | dirty = xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f); | ||
2538 | if (!dirty) | ||
2539 | goto out_release; | ||
2520 | } else { | 2540 | } else { |
2521 | xlog_recover_do_reg_buffer(mp, item, bp, buf_f); | 2541 | xlog_recover_do_reg_buffer(mp, item, bp, buf_f); |
2522 | } | 2542 | } |
2523 | if (error) | ||
2524 | goto out_release; | ||
2525 | 2543 | ||
2526 | /* | 2544 | /* |
2527 | * Perform delayed write on the buffer. Asynchronous writes will be | 2545 | * Perform delayed write on the buffer. Asynchronous writes will be |
@@ -3011,9 +3029,16 @@ xlog_recover_dquot_pass2( | |||
3011 | return -EIO; | 3029 | return -EIO; |
3012 | ASSERT(dq_f->qlf_len == 1); | 3030 | ASSERT(dq_f->qlf_len == 1); |
3013 | 3031 | ||
3032 | /* | ||
3033 | * At this point we are assuming that the dquots have been allocated | ||
3034 | * and hence the buffer has valid dquots stamped in it. It should, | ||
3035 | * therefore, pass verifier validation. If the dquot is bad, then the | ||
3036 | * we'll return an error here, so we don't need to specifically check | ||
3037 | * the dquot in the buffer after the verifier has run. | ||
3038 | */ | ||
3014 | error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dq_f->qlf_blkno, | 3039 | error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dq_f->qlf_blkno, |
3015 | XFS_FSB_TO_BB(mp, dq_f->qlf_len), 0, &bp, | 3040 | XFS_FSB_TO_BB(mp, dq_f->qlf_len), 0, &bp, |
3016 | NULL); | 3041 | &xfs_dquot_buf_ops); |
3017 | if (error) | 3042 | if (error) |
3018 | return error; | 3043 | return error; |
3019 | 3044 | ||
@@ -3021,18 +3046,6 @@ xlog_recover_dquot_pass2( | |||
3021 | ddq = (xfs_disk_dquot_t *)xfs_buf_offset(bp, dq_f->qlf_boffset); | 3046 | ddq = (xfs_disk_dquot_t *)xfs_buf_offset(bp, dq_f->qlf_boffset); |
3022 | 3047 | ||
3023 | /* | 3048 | /* |
3024 | * At least the magic num portion should be on disk because this | ||
3025 | * was among a chunk of dquots created earlier, and we did some | ||
3026 | * minimal initialization then. | ||
3027 | */ | ||
3028 | error = xfs_dqcheck(mp, ddq, dq_f->qlf_id, 0, XFS_QMOPT_DOWARN, | ||
3029 | "xlog_recover_dquot_pass2"); | ||
3030 | if (error) { | ||
3031 | xfs_buf_relse(bp); | ||
3032 | return -EIO; | ||
3033 | } | ||
3034 | |||
3035 | /* | ||
3036 | * If the dquot has an LSN in it, recover the dquot only if it's less | 3049 | * If the dquot has an LSN in it, recover the dquot only if it's less |
3037 | * than the lsn of the transaction we are replaying. | 3050 | * than the lsn of the transaction we are replaying. |
3038 | */ | 3051 | */ |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 5b639df0413e..fbf0384a466f 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -323,7 +323,6 @@ reread: | |||
323 | * Initialize the mount structure from the superblock. | 323 | * Initialize the mount structure from the superblock. |
324 | */ | 324 | */ |
325 | xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(bp)); | 325 | xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(bp)); |
326 | xfs_sb_quota_from_disk(sbp); | ||
327 | 326 | ||
328 | /* | 327 | /* |
329 | * If we haven't validated the superblock, do so now before we try | 328 | * If we haven't validated the superblock, do so now before we try |
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 7e1a80b45f87..10232102b4a6 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c | |||
@@ -911,6 +911,12 @@ xfs_qm_dqiter_bufs( | |||
911 | if (error) | 911 | if (error) |
912 | break; | 912 | break; |
913 | 913 | ||
914 | /* | ||
915 | * A corrupt buffer might not have a verifier attached, so | ||
916 | * make sure we have the correct one attached before writeback | ||
917 | * occurs. | ||
918 | */ | ||
919 | bp->b_ops = &xfs_dquot_buf_ops; | ||
914 | xfs_qm_reset_dqcounts(mp, bp, firstid, type); | 920 | xfs_qm_reset_dqcounts(mp, bp, firstid, type); |
915 | xfs_buf_delwri_queue(bp, buffer_list); | 921 | xfs_buf_delwri_queue(bp, buffer_list); |
916 | xfs_buf_relse(bp); | 922 | xfs_buf_relse(bp); |
@@ -996,7 +1002,7 @@ xfs_qm_dqiterate( | |||
996 | xfs_buf_readahead(mp->m_ddev_targp, | 1002 | xfs_buf_readahead(mp->m_ddev_targp, |
997 | XFS_FSB_TO_DADDR(mp, rablkno), | 1003 | XFS_FSB_TO_DADDR(mp, rablkno), |
998 | mp->m_quotainfo->qi_dqchunklen, | 1004 | mp->m_quotainfo->qi_dqchunklen, |
999 | NULL); | 1005 | &xfs_dquot_buf_ops); |
1000 | rablkno++; | 1006 | rablkno++; |
1001 | } | 1007 | } |
1002 | } | 1008 | } |
diff --git a/fs/xfs/xfs_vnode.h b/fs/xfs/xfs_vnode.h deleted file mode 100644 index e8a77383c0d5..000000000000 --- a/fs/xfs/xfs_vnode.h +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #ifndef __XFS_VNODE_H__ | ||
19 | #define __XFS_VNODE_H__ | ||
20 | |||
21 | #include "xfs_fs.h" | ||
22 | |||
23 | struct file; | ||
24 | struct xfs_inode; | ||
25 | struct attrlist_cursor_kern; | ||
26 | |||
27 | /* | ||
28 | * Flags for read/write calls - same values as IRIX | ||
29 | */ | ||
30 | #define IO_ISDIRECT 0x00004 /* bypass page cache */ | ||
31 | #define IO_INVIS 0x00020 /* don't update inode timestamps */ | ||
32 | |||
33 | #define XFS_IO_FLAGS \ | ||
34 | { IO_ISDIRECT, "DIRECT" }, \ | ||
35 | { IO_INVIS, "INVIS"} | ||
36 | |||
37 | /* | ||
38 | * Some useful predicates. | ||
39 | */ | ||
40 | #define VN_MAPPED(vp) mapping_mapped(vp->i_mapping) | ||
41 | #define VN_CACHED(vp) (vp->i_mapping->nrpages) | ||
42 | #define VN_DIRTY(vp) mapping_tagged(vp->i_mapping, \ | ||
43 | PAGECACHE_TAG_DIRTY) | ||
44 | |||
45 | |||
46 | #endif /* __XFS_VNODE_H__ */ | ||