aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <david@fromorbit.com>2014-08-03 23:55:27 -0400
committerDave Chinner <david@fromorbit.com>2014-08-03 23:55:27 -0400
commit645f9857213476407d8ed1b59619fdff7128d3e6 (patch)
treef48e76ffa8b4af8bfa0c64d54ff96d76b61f6f65 /fs/xfs
parentb076d8720d793cde04b75b4941b8774e209649b4 (diff)
parent4ef897a27543b513351262881660147366c042a1 (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.c24
-rw-r--r--fs/xfs/xfs_bmap_util.c100
-rw-r--r--fs/xfs/xfs_buf.c14
-rw-r--r--fs/xfs/xfs_dquot.c3
-rw-r--r--fs/xfs/xfs_file.c10
-rw-r--r--fs/xfs/xfs_inode.c2
-rw-r--r--fs/xfs/xfs_inode.h10
-rw-r--r--fs/xfs/xfs_ioctl.c6
-rw-r--r--fs/xfs/xfs_ioctl32.c3
-rw-r--r--fs/xfs/xfs_iops.c4
-rw-r--r--fs/xfs/xfs_linux.h2
-rw-r--r--fs/xfs/xfs_log.c8
-rw-r--r--fs/xfs/xfs_log_recover.c95
-rw-r--r--fs/xfs/xfs_mount.c1
-rw-r--r--fs/xfs/xfs_qm.c8
-rw-r--r--fs/xfs/xfs_vnode.h46
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
389void 389static void
390xfs_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
454void
455xfs_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
450static inline void 462static 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
1621int 1621int
1622xfs_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
1645int
1622xfs_swap_extents( 1646xfs_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
1889out_unlock: 1885out_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
1894out_trans_cancel: 1890out_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
399extern struct kmem_zone *xfs_inode_zone; 399extern 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 */
2409STATIC void 2406STATIC bool
2410xlog_recover_do_dquot_buffer( 2407xlog_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
23struct file;
24struct xfs_inode;
25struct 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__ */