Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f96736e1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-linus-v3.8-rc6' of git://oss.sgi.com/xfs/xfs

Pull xfs bugfixes from Ben Myers:
 "Here are fixes for returning EFSCORRUPTED on probe of a non-xfs
  filesystem, the stack switch in xfs_bmapi_allocate, a crash in
  _xfs_buf_find, speculative preallocation as the filesystem nears
  ENOSPC, an unmount hang, a race with AIO, and a regression with
  xfs_fsr:

   - fix return value when filesystem probe finds no XFS magic, a
     regression introduced in 98021821.

   - fix stack switch in __xfs_bmapi_allocate by moving the check for
     stack switch up into xfs_bmapi_write.

   - fix oops in _xfs_buf_find by validating that the requested block is
     within the filesystem bounds.

   - limit speculative preallocation near ENOSPC.

   - fix an unmount hang in xfs_wait_buftarg by freeing the
     xfs_buf_log_item in xfs_buf_item_unlock.

   - fix a possible use after free with AIO.

   - fix xfs_swap_extents after removal of xfs_flushinval_pages, a
     regression introduced in commit fb595814."

* tag 'for-linus-v3.8-rc6' of git://oss.sgi.com/xfs/xfs:
  xfs: Fix xfs_swap_extents() after removal of xfs_flushinval_pages()
  xfs: Fix possible use-after-free with AIO
  xfs: fix shutdown hang on invalid inode during create
  xfs: limit speculative prealloc near ENOSPC thresholds
  xfs: fix _xfs_buf_find oops on blocks beyond the filesystem end
  xfs: pull up stack_switch check into xfs_bmapi_write
  xfs: Do not return EFSCORRUPTED when filesystem probe finds no XFS magic
parents 8e5d573a 65e3aa77
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -86,11 +86,11 @@ xfs_destroy_ioend(
	}

	if (ioend->io_iocb) {
		inode_dio_done(ioend->io_inode);
		if (ioend->io_isasync) {
			aio_complete(ioend->io_iocb, ioend->io_error ?
					ioend->io_error : ioend->io_result, 0);
		}
		inode_dio_done(ioend->io_inode);
	}

	mempool_free(ioend, xfs_ioend_pool);
+3 −3
Original line number Diff line number Diff line
@@ -4680,9 +4680,6 @@ __xfs_bmapi_allocate(
			return error;
	}

	if (bma->flags & XFS_BMAPI_STACK_SWITCH)
		bma->stack_switch = 1;

	error = xfs_bmap_alloc(bma);
	if (error)
		return error;
@@ -4956,6 +4953,9 @@ xfs_bmapi_write(
	bma.flist = flist;
	bma.firstblock = firstblock;

	if (flags & XFS_BMAPI_STACK_SWITCH)
		bma.stack_switch = 1;

	while (bno < end && n < *nmap) {
		inhole = eof || bma.got.br_startoff > bno;
		wasdelay = !inhole && isnullstartblock(bma.got.br_startblock);
+20 −0
Original line number Diff line number Diff line
@@ -487,6 +487,7 @@ _xfs_buf_find(
	struct rb_node		*parent;
	xfs_buf_t		*bp;
	xfs_daddr_t		blkno = map[0].bm_bn;
	xfs_daddr_t		eofs;
	int			numblks = 0;
	int			i;

@@ -498,6 +499,23 @@ _xfs_buf_find(
	ASSERT(!(numbytes < (1 << btp->bt_sshift)));
	ASSERT(!(BBTOB(blkno) & (xfs_off_t)btp->bt_smask));

	/*
	 * Corrupted block numbers can get through to here, unfortunately, so we
	 * have to check that the buffer falls within the filesystem bounds.
	 */
	eofs = XFS_FSB_TO_BB(btp->bt_mount, btp->bt_mount->m_sb.sb_dblocks);
	if (blkno >= eofs) {
		/*
		 * XXX (dgc): we should really be returning EFSCORRUPTED here,
		 * but none of the higher level infrastructure supports
		 * returning a specific error on buffer lookup failures.
		 */
		xfs_alert(btp->bt_mount,
			  "%s: Block out of range: block 0x%llx, EOFS 0x%llx ",
			  __func__, blkno, eofs);
		return NULL;
	}

	/* get tree root */
	pag = xfs_perag_get(btp->bt_mount,
				xfs_daddr_to_agno(btp->bt_mount, blkno));
@@ -1487,6 +1505,8 @@ xfs_wait_buftarg(
	while (!list_empty(&btp->bt_lru)) {
		bp = list_first_entry(&btp->bt_lru, struct xfs_buf, b_lru);
		if (atomic_read(&bp->b_hold) > 1) {
			trace_xfs_buf_wait_buftarg(bp, _RET_IP_);
			list_move_tail(&bp->b_lru, &btp->bt_lru);
			spin_unlock(&btp->bt_lru_lock);
			delay(100);
			goto restart;
+10 −2
Original line number Diff line number Diff line
@@ -652,7 +652,10 @@ xfs_buf_item_unlock(

	/*
	 * If the buf item isn't tracking any data, free it, otherwise drop the
	 * reference we hold to it.
	 * reference we hold to it. If we are aborting the transaction, this may
	 * be the only reference to the buf item, so we free it anyway
	 * regardless of whether it is dirty or not. A dirty abort implies a
	 * shutdown, anyway.
	 */
	clean = 1;
	for (i = 0; i < bip->bli_format_count; i++) {
@@ -664,7 +667,12 @@ xfs_buf_item_unlock(
	}
	if (clean)
		xfs_buf_item_relse(bp);
	else
	else if (aborted) {
		if (atomic_dec_and_test(&bip->bli_refcount)) {
			ASSERT(XFS_FORCED_SHUTDOWN(lip->li_mountp));
			xfs_buf_item_relse(bp);
		}
	} else
		atomic_dec(&bip->bli_refcount);

	if (!hold)
+2 −2
Original line number Diff line number Diff line
@@ -246,10 +246,10 @@ xfs_swap_extents(
		goto out_unlock;
	}

	error = -filemap_write_and_wait(VFS_I(ip)->i_mapping);
	error = -filemap_write_and_wait(VFS_I(tip)->i_mapping);
	if (error)
		goto out_unlock;
	truncate_pagecache_range(VFS_I(ip), 0, -1);
	truncate_pagecache_range(VFS_I(tip), 0, -1);

	/* Verify O_DIRECT for ftmp */
	if (VN_CACHED(VFS_I(tip)) != 0) {
Loading