Skip to content

Commit 645f985

Browse files
committed
Merge branch 'xfs-misc-fixes-3.17-2' into for-next
2 parents b076d87 + 4ef897a commit 645f985

16 files changed

Lines changed: 175 additions & 161 deletions

fs/xfs/libxfs/xfs_sb.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -386,10 +386,11 @@ xfs_sb_quota_from_disk(struct xfs_sb *sbp)
386386
}
387387
}
388388

389-
void
390-
xfs_sb_from_disk(
389+
static void
390+
__xfs_sb_from_disk(
391391
struct xfs_sb *to,
392-
xfs_dsb_t *from)
392+
xfs_dsb_t *from,
393+
bool convert_xquota)
393394
{
394395
to->sb_magicnum = be32_to_cpu(from->sb_magicnum);
395396
to->sb_blocksize = be32_to_cpu(from->sb_blocksize);
@@ -445,6 +446,17 @@ xfs_sb_from_disk(
445446
to->sb_pad = 0;
446447
to->sb_pquotino = be64_to_cpu(from->sb_pquotino);
447448
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);
448460
}
449461

450462
static inline void
@@ -577,7 +589,11 @@ xfs_sb_verify(
577589
struct xfs_mount *mp = bp->b_target->bt_mount;
578590
struct xfs_sb sb;
579591

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);
581597

582598
/*
583599
* Only check the in progress field for the primary superblock as

fs/xfs/xfs_bmap_util.c

Lines changed: 48 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,7 @@ xfs_can_free_eofblocks(struct xfs_inode *ip, bool force)
809809
* have speculative prealloc/delalloc blocks to remove.
810810
*/
811811
if (VFS_I(ip)->i_size == 0 &&
812-
VN_CACHED(VFS_I(ip)) == 0 &&
812+
VFS_I(ip)->i_mapping->nrpages == 0 &&
813813
ip->i_delayed_blks == 0)
814814
return false;
815815

@@ -1618,6 +1618,30 @@ xfs_swap_extents_check_format(
16181618
return 0;
16191619
}
16201620

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+
16211645
int
16221646
xfs_swap_extents(
16231647
xfs_inode_t *ip, /* target inode */
@@ -1633,6 +1657,7 @@ xfs_swap_extents(
16331657
int aforkblks = 0;
16341658
int taforkblks = 0;
16351659
__uint64_t tmp;
1660+
int lock_flags;
16361661

16371662
tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL);
16381663
if (!tempifp) {
@@ -1641,13 +1666,13 @@ xfs_swap_extents(
16411666
}
16421667

16431668
/*
1644-
* we have to do two separate lock calls here to keep lockdep
1645-
* happy. If we try to get all the locks in one call, lock will
1646-
* report false positives when we drop the ILOCK and regain them
1647-
* below.
1669+
* Lock up the inodes against other IO and truncate to begin with.
1670+
* Then we can ensure the inodes are flushed and have no page cache
1671+
* safely. Once we have done this we can take the ilocks and do the rest
1672+
* of the checks.
16481673
*/
1674+
lock_flags = XFS_IOLOCK_EXCL;
16491675
xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL);
1650-
xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL);
16511676

16521677
/* Verify that both files have the same format */
16531678
if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) {
@@ -1661,23 +1686,28 @@ xfs_swap_extents(
16611686
goto out_unlock;
16621687
}
16631688

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);
16651693
if (error)
16661694
goto out_unlock;
1667-
truncate_pagecache_range(VFS_I(tip), 0, -1);
16681695

1669-
/* Verify O_DIRECT for ftmp */
1670-
if (VN_CACHED(VFS_I(tip)) != 0) {
1671-
error = -EINVAL;
1696+
tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT);
1697+
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0);
1698+
if (error) {
1699+
xfs_trans_cancel(tp, 0);
16721700
goto out_unlock;
16731701
}
1702+
xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL);
1703+
lock_flags |= XFS_ILOCK_EXCL;
16741704

16751705
/* Verify all data are being swapped */
16761706
if (sxp->sx_offset != 0 ||
16771707
sxp->sx_length != ip->i_d.di_size ||
16781708
sxp->sx_length != tip->i_d.di_size) {
16791709
error = -EFAULT;
1680-
goto out_unlock;
1710+
goto out_trans_cancel;
16811711
}
16821712

16831713
trace_xfs_swap_extent_before(ip, 0);
@@ -1689,7 +1719,7 @@ xfs_swap_extents(
16891719
xfs_notice(mp,
16901720
"%s: inode 0x%llx format is incompatible for exchanging.",
16911721
__func__, ip->i_ino);
1692-
goto out_unlock;
1722+
goto out_trans_cancel;
16931723
}
16941724

16951725
/*
@@ -1704,42 +1734,8 @@ xfs_swap_extents(
17041734
(sbp->bs_mtime.tv_sec != VFS_I(ip)->i_mtime.tv_sec) ||
17051735
(sbp->bs_mtime.tv_nsec != VFS_I(ip)->i_mtime.tv_nsec)) {
17061736
error = -EBUSY;
1707-
goto out_unlock;
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;
1737+
goto out_trans_cancel;
17401738
}
1741-
xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL);
1742-
17431739
/*
17441740
* Count the number of extended attribute blocks
17451741
*/
@@ -1757,8 +1753,8 @@ xfs_swap_extents(
17571753
goto out_trans_cancel;
17581754
}
17591755

1760-
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
1761-
xfs_trans_ijoin(tp, tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
1756+
xfs_trans_ijoin(tp, ip, lock_flags);
1757+
xfs_trans_ijoin(tp, tip, lock_flags);
17621758

17631759
/*
17641760
* Before we've swapped the forks, lets set the owners of the forks
@@ -1887,8 +1883,8 @@ xfs_swap_extents(
18871883
return error;
18881884

18891885
out_unlock:
1890-
xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
1891-
xfs_iunlock(tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
1886+
xfs_iunlock(ip, lock_flags);
1887+
xfs_iunlock(tip, lock_flags);
18921888
goto out;
18931889

18941890
out_trans_cancel:

fs/xfs/xfs_buf.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,6 +1330,20 @@ _xfs_buf_ioapply(
13301330
SHUTDOWN_CORRUPT_INCORE);
13311331
return;
13321332
}
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+
}
13331347
}
13341348
} else if (bp->b_flags & XBF_READ_AHEAD) {
13351349
rw = READA;

fs/xfs/xfs_dquot.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -974,7 +974,8 @@ xfs_qm_dqflush(
974974
* Get the buffer containing the on-disk dquot
975975
*/
976976
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);
978979
if (error)
979980
goto out_unlock;
980981

fs/xfs/xfs_file.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -247,11 +247,11 @@ xfs_file_read_iter(
247247
XFS_STATS_INC(xs_read_calls);
248248

249249
if (unlikely(file->f_flags & O_DIRECT))
250-
ioflags |= IO_ISDIRECT;
250+
ioflags |= XFS_IO_ISDIRECT;
251251
if (file->f_mode & FMODE_NOCMTIME)
252-
ioflags |= IO_INVIS;
252+
ioflags |= XFS_IO_INVIS;
253253

254-
if (unlikely(ioflags & IO_ISDIRECT)) {
254+
if (unlikely(ioflags & XFS_IO_ISDIRECT)) {
255255
xfs_buftarg_t *target =
256256
XFS_IS_REALTIME_INODE(ip) ?
257257
mp->m_rtdev_targp : mp->m_ddev_targp;
@@ -284,7 +284,7 @@ xfs_file_read_iter(
284284
* proceeed concurrently without serialisation.
285285
*/
286286
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) {
288288
xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED);
289289
xfs_rw_ilock(ip, XFS_IOLOCK_EXCL);
290290

@@ -326,7 +326,7 @@ xfs_file_splice_read(
326326
XFS_STATS_INC(xs_read_calls);
327327

328328
if (infilp->f_mode & FMODE_NOCMTIME)
329-
ioflags |= IO_INVIS;
329+
ioflags |= XFS_IO_INVIS;
330330

331331
if (XFS_FORCED_SHUTDOWN(ip->i_mount))
332332
return -EIO;

fs/xfs/xfs_inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1635,7 +1635,7 @@ xfs_release(
16351635
truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED);
16361636
if (truncated) {
16371637
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) {
16391639
error = filemap_flush(VFS_I(ip)->i_mapping);
16401640
if (error)
16411641
return error;

fs/xfs/xfs_inode.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,4 +398,14 @@ do { \
398398

399399
extern struct kmem_zone *xfs_inode_zone;
400400

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+
401411
#endif /* __XFS_INODE_H__ */

fs/xfs/xfs_ioctl.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ xfs_ioc_space(
736736
xfs_ilock(ip, XFS_ILOCK_EXCL);
737737
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
738738

739-
if (!(ioflags & IO_INVIS)) {
739+
if (!(ioflags & XFS_IO_INVIS)) {
740740
ip->i_d.di_mode &= ~S_ISUID;
741741
if (ip->i_d.di_mode & S_IXGRP)
742742
ip->i_d.di_mode &= ~S_ISGID;
@@ -1376,7 +1376,7 @@ xfs_ioc_getbmap(
13761376
return -EINVAL;
13771377

13781378
bmx.bmv_iflags = (cmd == XFS_IOC_GETBMAPA ? BMV_IF_ATTRFORK : 0);
1379-
if (ioflags & IO_INVIS)
1379+
if (ioflags & XFS_IO_INVIS)
13801380
bmx.bmv_iflags |= BMV_IF_NO_DMAPI_READ;
13811381

13821382
error = xfs_getbmap(ip, &bmx, xfs_getbmap_format,
@@ -1520,7 +1520,7 @@ xfs_file_ioctl(
15201520
int error;
15211521

15221522
if (filp->f_mode & FMODE_NOCMTIME)
1523-
ioflags |= IO_INVIS;
1523+
ioflags |= XFS_IO_INVIS;
15241524

15251525
trace_xfs_file_ioctl(ip);
15261526

fs/xfs/xfs_ioctl32.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
#include "xfs_sb.h"
2929
#include "xfs_ag.h"
3030
#include "xfs_mount.h"
31-
#include "xfs_vnode.h"
3231
#include "xfs_inode.h"
3332
#include "xfs_itable.h"
3433
#include "xfs_error.h"
@@ -537,7 +536,7 @@ xfs_file_compat_ioctl(
537536
int error;
538537

539538
if (filp->f_mode & FMODE_NOCMTIME)
540-
ioflags |= IO_INVIS;
539+
ioflags |= XFS_IO_INVIS;
541540

542541
trace_xfs_file_compat_ioctl(ip);
543542

fs/xfs/xfs_iops.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,12 +1055,12 @@ xfs_vn_fiemap(
10551055
return error;
10561056

10571057
/* Set up bmap header for xfs internal routine */
1058-
bm.bmv_offset = BTOBB(start);
1058+
bm.bmv_offset = BTOBBT(start);
10591059
/* Special case for whole file */
10601060
if (length == FIEMAP_MAX_OFFSET)
10611061
bm.bmv_length = -1LL;
10621062
else
1063-
bm.bmv_length = BTOBB(length);
1063+
bm.bmv_length = BTOBB(start + length) - bm.bmv_offset;
10641064

10651065
/* We add one because in getbmap world count includes the header */
10661066
bm.bmv_count = !fieinfo->fi_extents_max ? MAXEXTNUM :

0 commit comments

Comments
 (0)