Commit 50caca9d authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'xfs-5.5-merge-17' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull xfs fixes from Darrick Wong:
 "Fix a couple of resource management errors and a hang:

   - fix a crash in the log setup code when log mounting fails

   - fix a hang when allocating space on the realtime device

   - fix a block leak when freeing space on the realtime device"

* tag 'xfs-5.5-merge-17' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
  xfs: fix mount failure crash on invalid iclog memory access
  xfs: don't check for AG deadlock for realtime files in bunmapi
  xfs: fix realtime file data space leak
parents 316933cf 798a9cad
...@@ -5404,7 +5404,7 @@ __xfs_bunmapi( ...@@ -5404,7 +5404,7 @@ __xfs_bunmapi(
* Make sure we don't touch multiple AGF headers out of order * Make sure we don't touch multiple AGF headers out of order
* in a single transaction, as that could cause AB-BA deadlocks. * in a single transaction, as that could cause AB-BA deadlocks.
*/ */
if (!wasdel) { if (!wasdel && !isrt) {
agno = XFS_FSB_TO_AGNO(mp, del.br_startblock); agno = XFS_FSB_TO_AGNO(mp, del.br_startblock);
if (prev_agno != NULLAGNUMBER && prev_agno > agno) if (prev_agno != NULLAGNUMBER && prev_agno > agno)
break; break;
...@@ -5480,16 +5480,17 @@ __xfs_bunmapi( ...@@ -5480,16 +5480,17 @@ __xfs_bunmapi(
} }
div_u64_rem(del.br_startblock, mp->m_sb.sb_rextsize, &mod); div_u64_rem(del.br_startblock, mp->m_sb.sb_rextsize, &mod);
if (mod) { if (mod) {
xfs_extlen_t off = mp->m_sb.sb_rextsize - mod;
/* /*
* Realtime extent is lined up at the end but not * Realtime extent is lined up at the end but not
* at the front. We'll get rid of full extents if * at the front. We'll get rid of full extents if
* we can. * we can.
*/ */
mod = mp->m_sb.sb_rextsize - mod; if (del.br_blockcount > off) {
if (del.br_blockcount > mod) { del.br_blockcount -= off;
del.br_blockcount -= mod; del.br_startoff += off;
del.br_startoff += mod; del.br_startblock += off;
del.br_startblock += mod;
} else if (del.br_startoff == start && } else if (del.br_startoff == start &&
(del.br_state == XFS_EXT_UNWRITTEN || (del.br_state == XFS_EXT_UNWRITTEN ||
tp->t_blk_res == 0)) { tp->t_blk_res == 0)) {
...@@ -5507,6 +5508,7 @@ __xfs_bunmapi( ...@@ -5507,6 +5508,7 @@ __xfs_bunmapi(
continue; continue;
} else if (del.br_state == XFS_EXT_UNWRITTEN) { } else if (del.br_state == XFS_EXT_UNWRITTEN) {
struct xfs_bmbt_irec prev; struct xfs_bmbt_irec prev;
xfs_fileoff_t unwrite_start;
/* /*
* This one is already unwritten. * This one is already unwritten.
...@@ -5520,12 +5522,13 @@ __xfs_bunmapi( ...@@ -5520,12 +5522,13 @@ __xfs_bunmapi(
ASSERT(!isnullstartblock(prev.br_startblock)); ASSERT(!isnullstartblock(prev.br_startblock));
ASSERT(del.br_startblock == ASSERT(del.br_startblock ==
prev.br_startblock + prev.br_blockcount); prev.br_startblock + prev.br_blockcount);
if (prev.br_startoff < start) { unwrite_start = max3(start,
mod = start - prev.br_startoff; del.br_startoff - mod,
prev.br_blockcount -= mod; prev.br_startoff);
prev.br_startblock += mod; mod = unwrite_start - prev.br_startoff;
prev.br_startoff = start; prev.br_startoff = unwrite_start;
} prev.br_startblock += mod;
prev.br_blockcount -= mod;
prev.br_state = XFS_EXT_UNWRITTEN; prev.br_state = XFS_EXT_UNWRITTEN;
error = xfs_bmap_add_extent_unwritten_real(tp, error = xfs_bmap_add_extent_unwritten_real(tp,
ip, whichfork, &icur, &cur, ip, whichfork, &icur, &cur,
......
...@@ -1542,6 +1542,8 @@ xlog_alloc_log( ...@@ -1542,6 +1542,8 @@ xlog_alloc_log(
prev_iclog = iclog->ic_next; prev_iclog = iclog->ic_next;
kmem_free(iclog->ic_data); kmem_free(iclog->ic_data);
kmem_free(iclog); kmem_free(iclog);
if (prev_iclog == log->l_iclog)
break;
} }
out_free_log: out_free_log:
kmem_free(log); kmem_free(log);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment