Skip to content

Commit f2bdfda

Browse files
committed
Merge branch 'xfs-4.8-misc-fixes-4' into for-next
2 parents dc4113d + 72ccbbe commit f2bdfda

File tree

11 files changed

+259
-103
lines changed

11 files changed

+259
-103
lines changed

fs/xfs/libxfs/xfs_da_btree.c

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,6 @@ xfs_da3_split(
356356
struct xfs_da_state_blk *newblk;
357357
struct xfs_da_state_blk *addblk;
358358
struct xfs_da_intnode *node;
359-
struct xfs_buf *bp;
360359
int max;
361360
int action = 0;
362361
int error;
@@ -397,7 +396,9 @@ xfs_da3_split(
397396
break;
398397
}
399398
/*
400-
* Entry wouldn't fit, split the leaf again.
399+
* Entry wouldn't fit, split the leaf again. The new
400+
* extrablk will be consumed by xfs_da3_node_split if
401+
* the node is split.
401402
*/
402403
state->extravalid = 1;
403404
if (state->inleaf) {
@@ -445,6 +446,14 @@ xfs_da3_split(
445446
if (!addblk)
446447
return 0;
447448

449+
/*
450+
* xfs_da3_node_split() should have consumed any extra blocks we added
451+
* during a double leaf split in the attr fork. This is guaranteed as
452+
* we can't be here if the attr fork only has a single leaf block.
453+
*/
454+
ASSERT(state->extravalid == 0 ||
455+
state->path.blk[max].magic == XFS_DIR2_LEAFN_MAGIC);
456+
448457
/*
449458
* Split the root node.
450459
*/
@@ -457,43 +466,33 @@ xfs_da3_split(
457466
}
458467

459468
/*
460-
* Update pointers to the node which used to be block 0 and
461-
* just got bumped because of the addition of a new root node.
462-
* There might be three blocks involved if a double split occurred,
463-
* and the original block 0 could be at any position in the list.
469+
* Update pointers to the node which used to be block 0 and just got
470+
* bumped because of the addition of a new root node. Note that the
471+
* original block 0 could be at any position in the list of blocks in
472+
* the tree.
464473
*
465-
* Note: the magic numbers and sibling pointers are in the same
466-
* physical place for both v2 and v3 headers (by design). Hence it
467-
* doesn't matter which version of the xfs_da_intnode structure we use
468-
* here as the result will be the same using either structure.
474+
* Note: the magic numbers and sibling pointers are in the same physical
475+
* place for both v2 and v3 headers (by design). Hence it doesn't matter
476+
* which version of the xfs_da_intnode structure we use here as the
477+
* result will be the same using either structure.
469478
*/
470479
node = oldblk->bp->b_addr;
471480
if (node->hdr.info.forw) {
472-
if (be32_to_cpu(node->hdr.info.forw) == addblk->blkno) {
473-
bp = addblk->bp;
474-
} else {
475-
ASSERT(state->extravalid);
476-
bp = state->extrablk.bp;
477-
}
478-
node = bp->b_addr;
481+
ASSERT(be32_to_cpu(node->hdr.info.forw) == addblk->blkno);
482+
node = addblk->bp->b_addr;
479483
node->hdr.info.back = cpu_to_be32(oldblk->blkno);
480-
xfs_trans_log_buf(state->args->trans, bp,
481-
XFS_DA_LOGRANGE(node, &node->hdr.info,
482-
sizeof(node->hdr.info)));
484+
xfs_trans_log_buf(state->args->trans, addblk->bp,
485+
XFS_DA_LOGRANGE(node, &node->hdr.info,
486+
sizeof(node->hdr.info)));
483487
}
484488
node = oldblk->bp->b_addr;
485489
if (node->hdr.info.back) {
486-
if (be32_to_cpu(node->hdr.info.back) == addblk->blkno) {
487-
bp = addblk->bp;
488-
} else {
489-
ASSERT(state->extravalid);
490-
bp = state->extrablk.bp;
491-
}
492-
node = bp->b_addr;
490+
ASSERT(be32_to_cpu(node->hdr.info.back) == addblk->blkno);
491+
node = addblk->bp->b_addr;
493492
node->hdr.info.forw = cpu_to_be32(oldblk->blkno);
494-
xfs_trans_log_buf(state->args->trans, bp,
495-
XFS_DA_LOGRANGE(node, &node->hdr.info,
496-
sizeof(node->hdr.info)));
493+
xfs_trans_log_buf(state->args->trans, addblk->bp,
494+
XFS_DA_LOGRANGE(node, &node->hdr.info,
495+
sizeof(node->hdr.info)));
497496
}
498497
addblk->bp = NULL;
499498
return 0;

fs/xfs/xfs_aops.c

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,12 @@ xfs_find_bdev_for_inode(
8787
* We're now finished for good with this page. Update the page state via the
8888
* associated buffer_heads, paying attention to the start and end offsets that
8989
* we need to process on the page.
90+
*
91+
* Landmine Warning: bh->b_end_io() will call end_page_writeback() on the last
92+
* buffer in the IO. Once it does this, it is unsafe to access the bufferhead or
93+
* the page at all, as we may be racing with memory reclaim and it can free both
94+
* the bufferhead chain and the page as it will see the page as clean and
95+
* unused.
9096
*/
9197
static void
9298
xfs_finish_page_writeback(
@@ -95,8 +101,9 @@ xfs_finish_page_writeback(
95101
int error)
96102
{
97103
unsigned int end = bvec->bv_offset + bvec->bv_len - 1;
98-
struct buffer_head *head, *bh;
104+
struct buffer_head *head, *bh, *next;
99105
unsigned int off = 0;
106+
unsigned int bsize;
100107

101108
ASSERT(bvec->bv_offset < PAGE_SIZE);
102109
ASSERT((bvec->bv_offset & ((1 << inode->i_blkbits) - 1)) == 0);
@@ -105,15 +112,17 @@ xfs_finish_page_writeback(
105112

106113
bh = head = page_buffers(bvec->bv_page);
107114

115+
bsize = bh->b_size;
108116
do {
117+
next = bh->b_this_page;
109118
if (off < bvec->bv_offset)
110119
goto next_bh;
111120
if (off > end)
112121
break;
113122
bh->b_end_io(bh, !error);
114123
next_bh:
115-
off += bh->b_size;
116-
} while ((bh = bh->b_this_page) != head);
124+
off += bsize;
125+
} while ((bh = next) != head);
117126
}
118127

119128
/*
@@ -1040,6 +1049,20 @@ xfs_vm_releasepage(
10401049

10411050
trace_xfs_releasepage(page->mapping->host, page, 0, 0);
10421051

1052+
/*
1053+
* mm accommodates an old ext3 case where clean pages might not have had
1054+
* the dirty bit cleared. Thus, it can send actual dirty pages to
1055+
* ->releasepage() via shrink_active_list(). Conversely,
1056+
* block_invalidatepage() can send pages that are still marked dirty
1057+
* but otherwise have invalidated buffers.
1058+
*
1059+
* We've historically freed buffers on the latter. Instead, quietly
1060+
* filter out all dirty pages to avoid spurious buffer state warnings.
1061+
* This can likely be removed once shrink_active_list() is fixed.
1062+
*/
1063+
if (PageDirty(page))
1064+
return 0;
1065+
10431066
xfs_count_page_state(page, &delalloc, &unwritten);
10441067

10451068
if (WARN_ON_ONCE(delalloc))

fs/xfs/xfs_buf_item.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,7 @@ xfs_buf_item_free(
957957
xfs_buf_log_item_t *bip)
958958
{
959959
xfs_buf_item_free_format(bip);
960+
kmem_free(bip->bli_item.li_lv_shadow);
960961
kmem_zone_free(xfs_buf_item_zone, bip);
961962
}
962963

fs/xfs/xfs_dquot.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ xfs_qm_dqdestroy(
7474
{
7575
ASSERT(list_empty(&dqp->q_lru));
7676

77+
kmem_free(dqp->q_logitem.qli_item.li_lv_shadow);
7778
mutex_destroy(&dqp->q_qlock);
7879

7980
XFS_STATS_DEC(dqp->q_mount, xs_qm_dquot);

fs/xfs/xfs_dquot_item.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,8 @@ xfs_qm_qoffend_logitem_committed(
370370
spin_lock(&ailp->xa_lock);
371371
xfs_trans_ail_delete(ailp, &qfs->qql_item, SHUTDOWN_LOG_IO_ERROR);
372372

373+
kmem_free(qfs->qql_item.li_lv_shadow);
374+
kmem_free(lip->li_lv_shadow);
373375
kmem_free(qfs);
374376
kmem_free(qfe);
375377
return (xfs_lsn_t)-1;

fs/xfs/xfs_extfree_item.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ void
4040
xfs_efi_item_free(
4141
struct xfs_efi_log_item *efip)
4242
{
43+
kmem_free(efip->efi_item.li_lv_shadow);
4344
if (efip->efi_format.efi_nextents > XFS_EFI_MAX_FAST_EXTENTS)
4445
kmem_free(efip);
4546
else
@@ -300,6 +301,7 @@ static inline struct xfs_efd_log_item *EFD_ITEM(struct xfs_log_item *lip)
300301
STATIC void
301302
xfs_efd_item_free(struct xfs_efd_log_item *efdp)
302303
{
304+
kmem_free(efdp->efd_item.li_lv_shadow);
303305
if (efdp->efd_format.efd_nextents > XFS_EFD_MAX_FAST_EXTENTS)
304306
kmem_free(efdp);
305307
else

fs/xfs/xfs_file.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ xfs_file_dio_aio_read(
327327
return ret;
328328
}
329329

330-
STATIC ssize_t
330+
static noinline ssize_t
331331
xfs_file_dax_read(
332332
struct kiocb *iocb,
333333
struct iov_iter *to)
@@ -706,7 +706,7 @@ xfs_file_dio_aio_write(
706706
return ret;
707707
}
708708

709-
STATIC ssize_t
709+
static noinline ssize_t
710710
xfs_file_dax_write(
711711
struct kiocb *iocb,
712712
struct iov_iter *from)

fs/xfs/xfs_inode_item.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,7 @@ void
651651
xfs_inode_item_destroy(
652652
xfs_inode_t *ip)
653653
{
654+
kmem_free(ip->i_itemp->ili_item.li_lv_shadow);
654655
kmem_zone_free(xfs_ili_zone, ip->i_itemp);
655656
}
656657

0 commit comments

Comments
 (0)