Skip to content

Commit 02a2b05

Browse files
committed
Merge tag 'xfs-4.14-fixes-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull xfs fixes from Darrick Wong: - fix various problems with the copy-on-write extent maps getting freed at the wrong time - fix printk format specifier problems - report zeroing operation outcomes instead of dropping them on the floor - fix some crashes when dio operations partially fail - fix a race condition between unwritten extent conversion & dio read - fix some incorrect tests in the inode log item processing - correct the delayed allocation space reservations on rmap filesystems - fix some problems checking for dax support * tag 'xfs-4.14-fixes-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: xfs: revert "xfs: factor rmap btree size into the indlen calculations" xfs: Capture state of the right inode in xfs_iflush_done xfs: perag initialization should only touch m_ag_max_usable for AG 0 xfs: update i_size after unwritten conversion in dio completion iomap_dio_rw: Allocate AIO completion queue before submitting dio xfs: validate bdev support for DAX inode flag xfs: remove redundant re-initialization of total_nr_pages xfs: Output warning message when discard option was enabled even though the device does not support discard xfs: report zeroed or not correctly in xfs_zero_range() xfs: kill meaningless variable 'zero' fs/xfs: Use %pS printk format for direct addresses xfs: evict CoW fork extents when performing finsert/fcollapse xfs: don't unconditionally clear the reflink flag on zero-block files
2 parents e49aa15 + 5e5c943 commit 02a2b05

15 files changed

+81
-56
lines changed

fs/iomap.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,13 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
10091009
WARN_ON_ONCE(ret);
10101010
ret = 0;
10111011

1012+
if (iov_iter_rw(iter) == WRITE && !is_sync_kiocb(iocb) &&
1013+
!inode->i_sb->s_dio_done_wq) {
1014+
ret = sb_init_dio_done_wq(inode->i_sb);
1015+
if (ret < 0)
1016+
goto out_free_dio;
1017+
}
1018+
10121019
inode_dio_begin(inode);
10131020

10141021
blk_start_plug(&plug);
@@ -1031,13 +1038,6 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
10311038
if (ret < 0)
10321039
iomap_dio_set_error(dio, ret);
10331040

1034-
if (ret >= 0 && iov_iter_rw(iter) == WRITE && !is_sync_kiocb(iocb) &&
1035-
!inode->i_sb->s_dio_done_wq) {
1036-
ret = sb_init_dio_done_wq(inode->i_sb);
1037-
if (ret < 0)
1038-
iomap_dio_set_error(dio, ret);
1039-
}
1040-
10411041
if (!atomic_dec_and_test(&dio->ref)) {
10421042
if (!is_sync_kiocb(iocb))
10431043
return -EIOCBQUEUED;

fs/xfs/libxfs/xfs_ag_resv.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ __xfs_ag_resv_free(
156156
trace_xfs_ag_resv_free(pag, type, 0);
157157

158158
resv = xfs_perag_resv(pag, type);
159-
pag->pag_mount->m_ag_max_usable += resv->ar_asked;
159+
if (pag->pag_agno == 0)
160+
pag->pag_mount->m_ag_max_usable += resv->ar_asked;
160161
/*
161162
* AGFL blocks are always considered "free", so whatever
162163
* was reserved at mount time must be given back at umount.
@@ -216,7 +217,14 @@ __xfs_ag_resv_init(
216217
return error;
217218
}
218219

219-
mp->m_ag_max_usable -= ask;
220+
/*
221+
* Reduce the maximum per-AG allocation length by however much we're
222+
* trying to reserve for an AG. Since this is a filesystem-wide
223+
* counter, we only make the adjustment for AG 0. This assumes that
224+
* there aren't any AGs hungrier for per-AG reservation than AG 0.
225+
*/
226+
if (pag->pag_agno == 0)
227+
mp->m_ag_max_usable -= ask;
220228

221229
resv = xfs_perag_resv(pag, type);
222230
resv->ar_asked = ask;

fs/xfs/libxfs/xfs_bmap.c

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
#include "xfs_rmap.h"
5050
#include "xfs_ag_resv.h"
5151
#include "xfs_refcount.h"
52-
#include "xfs_rmap_btree.h"
5352
#include "xfs_icache.h"
5453

5554

@@ -192,33 +191,21 @@ xfs_bmap_worst_indlen(
192191
int maxrecs; /* maximum record count at this level */
193192
xfs_mount_t *mp; /* mount structure */
194193
xfs_filblks_t rval; /* return value */
195-
xfs_filblks_t orig_len;
196194

197195
mp = ip->i_mount;
198-
199-
/* Calculate the worst-case size of the bmbt. */
200-
orig_len = len;
201196
maxrecs = mp->m_bmap_dmxr[0];
202197
for (level = 0, rval = 0;
203198
level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK);
204199
level++) {
205200
len += maxrecs - 1;
206201
do_div(len, maxrecs);
207202
rval += len;
208-
if (len == 1) {
209-
rval += XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) -
203+
if (len == 1)
204+
return rval + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) -
210205
level - 1;
211-
break;
212-
}
213206
if (level == 0)
214207
maxrecs = mp->m_bmap_dmxr[1];
215208
}
216-
217-
/* Calculate the worst-case size of the rmapbt. */
218-
if (xfs_sb_version_hasrmapbt(&mp->m_sb))
219-
rval += 1 + xfs_rmapbt_calc_size(mp, orig_len) +
220-
mp->m_rmap_maxlevels;
221-
222209
return rval;
223210
}
224211

fs/xfs/xfs_aops.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,8 @@ xfs_end_io(
343343
error = xfs_reflink_end_cow(ip, offset, size);
344344
break;
345345
case XFS_IO_UNWRITTEN:
346-
error = xfs_iomap_write_unwritten(ip, offset, size);
346+
/* writeback should never update isize */
347+
error = xfs_iomap_write_unwritten(ip, offset, size, false);
347348
break;
348349
default:
349350
ASSERT(!xfs_ioend_is_append(ioend) || ioend->io_append_trans);

fs/xfs/xfs_bmap_util.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1459,7 +1459,19 @@ xfs_shift_file_space(
14591459
return error;
14601460

14611461
/*
1462-
* The extent shiting code works on extent granularity. So, if
1462+
* Clean out anything hanging around in the cow fork now that
1463+
* we've flushed all the dirty data out to disk to avoid having
1464+
* CoW extents at the wrong offsets.
1465+
*/
1466+
if (xfs_is_reflink_inode(ip)) {
1467+
error = xfs_reflink_cancel_cow_range(ip, offset, NULLFILEOFF,
1468+
true);
1469+
if (error)
1470+
return error;
1471+
}
1472+
1473+
/*
1474+
* The extent shifting code works on extent granularity. So, if
14631475
* stop_fsb is not the starting block of extent, we need to split
14641476
* the extent at stop_fsb.
14651477
*/

fs/xfs/xfs_buf.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,8 +1258,6 @@ xfs_buf_ioapply_map(
12581258
int size;
12591259
int offset;
12601260

1261-
total_nr_pages = bp->b_page_count;
1262-
12631261
/* skip the pages in the buffer before the start offset */
12641262
page_index = 0;
12651263
offset = *buf_offset;

fs/xfs/xfs_error.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ xfs_verifier_error(
347347
{
348348
struct xfs_mount *mp = bp->b_target->bt_mount;
349349

350-
xfs_alert(mp, "Metadata %s detected at %pF, %s block 0x%llx",
350+
xfs_alert(mp, "Metadata %s detected at %pS, %s block 0x%llx",
351351
bp->b_error == -EFSBADCRC ? "CRC error" : "corruption",
352352
__return_address, bp->b_ops->name, bp->b_bn);
353353

fs/xfs/xfs_file.c

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ xfs_zero_range(
5858
xfs_off_t count,
5959
bool *did_zero)
6060
{
61-
return iomap_zero_range(VFS_I(ip), pos, count, NULL, &xfs_iomap_ops);
61+
return iomap_zero_range(VFS_I(ip), pos, count, did_zero, &xfs_iomap_ops);
6262
}
6363

6464
int
@@ -377,8 +377,6 @@ xfs_file_aio_write_checks(
377377
*/
378378
spin_lock(&ip->i_flags_lock);
379379
if (iocb->ki_pos > i_size_read(inode)) {
380-
bool zero = false;
381-
382380
spin_unlock(&ip->i_flags_lock);
383381
if (!drained_dio) {
384382
if (*iolock == XFS_IOLOCK_SHARED) {
@@ -399,7 +397,7 @@ xfs_file_aio_write_checks(
399397
drained_dio = true;
400398
goto restart;
401399
}
402-
error = xfs_zero_eof(ip, iocb->ki_pos, i_size_read(inode), &zero);
400+
error = xfs_zero_eof(ip, iocb->ki_pos, i_size_read(inode), NULL);
403401
if (error)
404402
return error;
405403
} else
@@ -436,7 +434,6 @@ xfs_dio_write_end_io(
436434
struct inode *inode = file_inode(iocb->ki_filp);
437435
struct xfs_inode *ip = XFS_I(inode);
438436
loff_t offset = iocb->ki_pos;
439-
bool update_size = false;
440437
int error = 0;
441438

442439
trace_xfs_end_io_direct_write(ip, offset, size);
@@ -447,6 +444,21 @@ xfs_dio_write_end_io(
447444
if (size <= 0)
448445
return size;
449446

447+
if (flags & IOMAP_DIO_COW) {
448+
error = xfs_reflink_end_cow(ip, offset, size);
449+
if (error)
450+
return error;
451+
}
452+
453+
/*
454+
* Unwritten conversion updates the in-core isize after extent
455+
* conversion but before updating the on-disk size. Updating isize any
456+
* earlier allows a racing dio read to find unwritten extents before
457+
* they are converted.
458+
*/
459+
if (flags & IOMAP_DIO_UNWRITTEN)
460+
return xfs_iomap_write_unwritten(ip, offset, size, true);
461+
450462
/*
451463
* We need to update the in-core inode size here so that we don't end up
452464
* with the on-disk inode size being outside the in-core inode size. We
@@ -461,20 +473,11 @@ xfs_dio_write_end_io(
461473
spin_lock(&ip->i_flags_lock);
462474
if (offset + size > i_size_read(inode)) {
463475
i_size_write(inode, offset + size);
464-
update_size = true;
465-
}
466-
spin_unlock(&ip->i_flags_lock);
467-
468-
if (flags & IOMAP_DIO_COW) {
469-
error = xfs_reflink_end_cow(ip, offset, size);
470-
if (error)
471-
return error;
472-
}
473-
474-
if (flags & IOMAP_DIO_UNWRITTEN)
475-
error = xfs_iomap_write_unwritten(ip, offset, size);
476-
else if (update_size)
476+
spin_unlock(&ip->i_flags_lock);
477477
error = xfs_setfilesize(ip, offset, size);
478+
} else {
479+
spin_unlock(&ip->i_flags_lock);
480+
}
478481

479482
return error;
480483
}

fs/xfs/xfs_inode.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,10 +1624,12 @@ xfs_itruncate_extents(
16241624
goto out;
16251625

16261626
/*
1627-
* Clear the reflink flag if we truncated everything.
1627+
* Clear the reflink flag if there are no data fork blocks and
1628+
* there are no extents staged in the cow fork.
16281629
*/
1629-
if (ip->i_d.di_nblocks == 0 && xfs_is_reflink_inode(ip)) {
1630-
ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
1630+
if (xfs_is_reflink_inode(ip) && ip->i_cnextents == 0) {
1631+
if (ip->i_d.di_nblocks == 0)
1632+
ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
16311633
xfs_inode_clear_cowblocks_tag(ip);
16321634
}
16331635

fs/xfs/xfs_inode_item.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,7 @@ xfs_iflush_done(
745745
*/
746746
iip = INODE_ITEM(blip);
747747
if ((iip->ili_logged && blip->li_lsn == iip->ili_flush_lsn) ||
748-
lip->li_flags & XFS_LI_FAILED)
748+
(blip->li_flags & XFS_LI_FAILED))
749749
need_ail++;
750750

751751
blip = next;

fs/xfs/xfs_ioctl.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1088,6 +1088,7 @@ xfs_ioctl_setattr_dax_invalidate(
10881088
int *join_flags)
10891089
{
10901090
struct inode *inode = VFS_I(ip);
1091+
struct super_block *sb = inode->i_sb;
10911092
int error;
10921093

10931094
*join_flags = 0;
@@ -1100,7 +1101,7 @@ xfs_ioctl_setattr_dax_invalidate(
11001101
if (fa->fsx_xflags & FS_XFLAG_DAX) {
11011102
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
11021103
return -EINVAL;
1103-
if (ip->i_mount->m_sb.sb_blocksize != PAGE_SIZE)
1104+
if (bdev_dax_supported(sb, sb->s_blocksize) < 0)
11041105
return -EINVAL;
11051106
}
11061107

fs/xfs/xfs_iomap.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,8 @@ int
829829
xfs_iomap_write_unwritten(
830830
xfs_inode_t *ip,
831831
xfs_off_t offset,
832-
xfs_off_t count)
832+
xfs_off_t count,
833+
bool update_isize)
833834
{
834835
xfs_mount_t *mp = ip->i_mount;
835836
xfs_fileoff_t offset_fsb;
@@ -840,6 +841,7 @@ xfs_iomap_write_unwritten(
840841
xfs_trans_t *tp;
841842
xfs_bmbt_irec_t imap;
842843
struct xfs_defer_ops dfops;
844+
struct inode *inode = VFS_I(ip);
843845
xfs_fsize_t i_size;
844846
uint resblks;
845847
int error;
@@ -899,7 +901,8 @@ xfs_iomap_write_unwritten(
899901
i_size = XFS_FSB_TO_B(mp, offset_fsb + count_fsb);
900902
if (i_size > offset + count)
901903
i_size = offset + count;
902-
904+
if (update_isize && i_size > i_size_read(inode))
905+
i_size_write(inode, i_size);
903906
i_size = xfs_new_eof(ip, i_size);
904907
if (i_size) {
905908
ip->i_d.di_size = i_size;

fs/xfs/xfs_iomap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t,
2727
struct xfs_bmbt_irec *, int);
2828
int xfs_iomap_write_allocate(struct xfs_inode *, int, xfs_off_t,
2929
struct xfs_bmbt_irec *);
30-
int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t);
30+
int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t, bool);
3131

3232
void xfs_bmbt_to_iomap(struct xfs_inode *, struct iomap *,
3333
struct xfs_bmbt_irec *);

fs/xfs/xfs_pnfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ xfs_fs_commit_blocks(
274274
(end - 1) >> PAGE_SHIFT);
275275
WARN_ON_ONCE(error);
276276

277-
error = xfs_iomap_write_unwritten(ip, start, length);
277+
error = xfs_iomap_write_unwritten(ip, start, length, false);
278278
if (error)
279279
goto out_drop_iolock;
280280
}

fs/xfs/xfs_super.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1654,6 +1654,16 @@ xfs_fs_fill_super(
16541654
"DAX and reflink have not been tested together!");
16551655
}
16561656

1657+
if (mp->m_flags & XFS_MOUNT_DISCARD) {
1658+
struct request_queue *q = bdev_get_queue(sb->s_bdev);
1659+
1660+
if (!blk_queue_discard(q)) {
1661+
xfs_warn(mp, "mounting with \"discard\" option, but "
1662+
"the device does not support discard");
1663+
mp->m_flags &= ~XFS_MOUNT_DISCARD;
1664+
}
1665+
}
1666+
16571667
if (xfs_sb_version_hasrmapbt(&mp->m_sb)) {
16581668
if (mp->m_sb.sb_rblocks) {
16591669
xfs_alert(mp,

0 commit comments

Comments
 (0)