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

Commit 0d907a3b authored by Dave Chinner's avatar Dave Chinner
Browse files

Merge branch 'xfs-misc-fixes-2-for-3.16' into for-next

Conflicts:
	fs/xfs/xfs_ialloc.c
parents 2d6dcc6d 376c2f3a
Loading
Loading
Loading
Loading
+43 −6
Original line number Original line Diff line number Diff line
@@ -982,7 +982,32 @@ xfs_vm_writepage(
	offset = i_size_read(inode);
	offset = i_size_read(inode);
	end_index = offset >> PAGE_CACHE_SHIFT;
	end_index = offset >> PAGE_CACHE_SHIFT;
	last_index = (offset - 1) >> PAGE_CACHE_SHIFT;
	last_index = (offset - 1) >> PAGE_CACHE_SHIFT;
	if (page->index >= end_index) {

	/*
	 * The page index is less than the end_index, adjust the end_offset
	 * to the highest offset that this page should represent.
	 * -----------------------------------------------------
	 * |			file mapping	       | <EOF> |
	 * -----------------------------------------------------
	 * | Page ... | Page N-2 | Page N-1 |  Page N  |       |
	 * ^--------------------------------^----------|--------
	 * |     desired writeback range    |      see else    |
	 * ---------------------------------^------------------|
	 */
	if (page->index < end_index)
		end_offset = (xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT;
	else {
		/*
		 * Check whether the page to write out is beyond or straddles
		 * i_size or not.
		 * -------------------------------------------------------
		 * |		file mapping		        | <EOF>  |
		 * -------------------------------------------------------
		 * | Page ... | Page N-2 | Page N-1 |  Page N   | Beyond |
		 * ^--------------------------------^-----------|---------
		 * |				    |      Straddles     |
		 * ---------------------------------^-----------|--------|
		 */
		unsigned offset_into_page = offset & (PAGE_CACHE_SIZE - 1);
		unsigned offset_into_page = offset & (PAGE_CACHE_SIZE - 1);


		/*
		/*
@@ -990,8 +1015,20 @@ xfs_vm_writepage(
		 * truncate operation that is in progress. We must redirty the
		 * truncate operation that is in progress. We must redirty the
		 * page so that reclaim stops reclaiming it. Otherwise
		 * page so that reclaim stops reclaiming it. Otherwise
		 * xfs_vm_releasepage() is called on it and gets confused.
		 * xfs_vm_releasepage() is called on it and gets confused.
		 *
		 * Note that the end_index is unsigned long, it would overflow
		 * if the given offset is greater than 16TB on 32-bit system
		 * and if we do check the page is fully outside i_size or not
		 * via "if (page->index >= end_index + 1)" as "end_index + 1"
		 * will be evaluated to 0.  Hence this page will be redirtied
		 * and be written out repeatedly which would result in an
		 * infinite loop, the user program that perform this operation
		 * will hang.  Instead, we can verify this situation by checking
		 * if the page to write is totally beyond the i_size or if it's
		 * offset is just equal to the EOF.
		 */
		 */
		if (page->index >= end_index + 1 || offset_into_page == 0)
		if (page->index > end_index ||
		    (page->index == end_index && offset_into_page == 0))
			goto redirty;
			goto redirty;


		/*
		/*
@@ -1003,11 +1040,11 @@ xfs_vm_writepage(
		 * not written out to the file."
		 * not written out to the file."
		 */
		 */
		zero_user_segment(page, offset_into_page, PAGE_CACHE_SIZE);
		zero_user_segment(page, offset_into_page, PAGE_CACHE_SIZE);

		/* Adjust the end_offset to the end of file */
		end_offset = offset;
	}
	}


	end_offset = min_t(unsigned long long,
			(xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT,
			offset);
	len = 1 << inode->i_blkbits;
	len = 1 << inode->i_blkbits;


	bh = head = page_buffers(page);
	bh = head = page_buffers(page);
+0 −2
Original line number Original line Diff line number Diff line
@@ -1519,7 +1519,6 @@ xfs_collapse_file_space(


	while (!error && !done) {
	while (!error && !done) {
		tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
		tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
		tp->t_flags |= XFS_TRANS_RESERVE;
		/*
		/*
		 * We would need to reserve permanent block for transaction.
		 * We would need to reserve permanent block for transaction.
		 * This will come into picture when after shifting extent into
		 * This will come into picture when after shifting extent into
@@ -1529,7 +1528,6 @@ xfs_collapse_file_space(
		error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write,
		error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write,
				XFS_DIOSTRAT_SPACE_RES(mp, 0), 0);
				XFS_DIOSTRAT_SPACE_RES(mp, 0), 0);
		if (error) {
		if (error) {
			ASSERT(error == ENOSPC || XFS_FORCED_SHUTDOWN(mp));
			xfs_trans_cancel(tp, 0);
			xfs_trans_cancel(tp, 0);
			break;
			break;
		}
		}
+0 −41
Original line number Original line Diff line number Diff line
@@ -2624,47 +2624,6 @@ xfs_da_read_buf(
		xfs_buf_set_ref(bp, XFS_ATTR_BTREE_REF);
		xfs_buf_set_ref(bp, XFS_ATTR_BTREE_REF);
	else
	else
		xfs_buf_set_ref(bp, XFS_DIR_BTREE_REF);
		xfs_buf_set_ref(bp, XFS_DIR_BTREE_REF);

	/*
	 * This verification code will be moved to a CRC verification callback
	 * function so just leave it here unchanged until then.
	 */
	{
		xfs_dir2_data_hdr_t	*hdr = bp->b_addr;
		xfs_dir2_free_t		*free = bp->b_addr;
		xfs_da_blkinfo_t	*info = bp->b_addr;
		uint			magic, magic1;
		struct xfs_mount	*mp = dp->i_mount;

		magic = be16_to_cpu(info->magic);
		magic1 = be32_to_cpu(hdr->magic);
		if (unlikely(
		    XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
				   (magic != XFS_DA3_NODE_MAGIC) &&
				   (magic != XFS_ATTR_LEAF_MAGIC) &&
				   (magic != XFS_ATTR3_LEAF_MAGIC) &&
				   (magic != XFS_DIR2_LEAF1_MAGIC) &&
				   (magic != XFS_DIR3_LEAF1_MAGIC) &&
				   (magic != XFS_DIR2_LEAFN_MAGIC) &&
				   (magic != XFS_DIR3_LEAFN_MAGIC) &&
				   (magic1 != XFS_DIR2_BLOCK_MAGIC) &&
				   (magic1 != XFS_DIR3_BLOCK_MAGIC) &&
				   (magic1 != XFS_DIR2_DATA_MAGIC) &&
				   (magic1 != XFS_DIR3_DATA_MAGIC) &&
				   (free->hdr.magic !=
					cpu_to_be32(XFS_DIR2_FREE_MAGIC)) &&
				   (free->hdr.magic !=
					cpu_to_be32(XFS_DIR3_FREE_MAGIC)),
				mp, XFS_ERRTAG_DA_READ_BUF,
				XFS_RANDOM_DA_READ_BUF))) {
			trace_xfs_da_btree_corrupt(bp, _RET_IP_);
			XFS_CORRUPTION_ERROR("xfs_da_do_buf(2)",
					     XFS_ERRLEVEL_LOW, mp, info);
			error = XFS_ERROR(EFSCORRUPTED);
			xfs_trans_brelse(trans, bp);
			goto out_free;
		}
	}
	*bpp = bp;
	*bpp = bp;
out_free:
out_free:
	if (mapp != &map)
	if (mapp != &map)
+5 −5
Original line number Original line Diff line number Diff line
@@ -1437,7 +1437,7 @@ xfs_difree_inobt(
	struct xfs_buf			*agbp,
	struct xfs_buf			*agbp,
	xfs_agino_t			agino,
	xfs_agino_t			agino,
	struct xfs_bmap_free		*flist,
	struct xfs_bmap_free		*flist,
	int				*delete,
	int				*deleted,
	xfs_ino_t			*first_ino,
	xfs_ino_t			*first_ino,
	struct xfs_inobt_rec_incore	*orec)
	struct xfs_inobt_rec_incore	*orec)
{
{
@@ -1497,7 +1497,7 @@ xfs_difree_inobt(
	if (!(mp->m_flags & XFS_MOUNT_IKEEP) &&
	if (!(mp->m_flags & XFS_MOUNT_IKEEP) &&
	    (rec.ir_freecount == mp->m_ialloc_inos)) {
	    (rec.ir_freecount == mp->m_ialloc_inos)) {


		*delete = 1;
		*deleted = 1;
		*first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino);
		*first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino);


		/*
		/*
@@ -1525,7 +1525,7 @@ xfs_difree_inobt(
				  XFS_AGINO_TO_AGBNO(mp, rec.ir_startino)),
				  XFS_AGINO_TO_AGBNO(mp, rec.ir_startino)),
				  mp->m_ialloc_blks, flist, mp);
				  mp->m_ialloc_blks, flist, mp);
	} else {
	} else {
		*delete = 0;
		*deleted = 0;


		error = xfs_inobt_update(cur, &rec);
		error = xfs_inobt_update(cur, &rec);
		if (error) {
		if (error) {
@@ -1662,7 +1662,7 @@ xfs_difree(
	struct xfs_trans	*tp,		/* transaction pointer */
	struct xfs_trans	*tp,		/* transaction pointer */
	xfs_ino_t		inode,		/* inode to be freed */
	xfs_ino_t		inode,		/* inode to be freed */
	struct xfs_bmap_free	*flist,		/* extents to free */
	struct xfs_bmap_free	*flist,		/* extents to free */
	int			*delete,/* set if inode cluster was deleted */
	int			*deleted,/* set if inode cluster was deleted */
	xfs_ino_t		*first_ino)/* first inode in deleted cluster */
	xfs_ino_t		*first_ino)/* first inode in deleted cluster */
{
{
	/* REFERENCED */
	/* REFERENCED */
@@ -1714,7 +1714,7 @@ xfs_difree(
	/*
	/*
	 * Fix up the inode allocation btree.
	 * Fix up the inode allocation btree.
	 */
	 */
	error = xfs_difree_inobt(mp, tp, agbp, agino, flist, delete, first_ino,
	error = xfs_difree_inobt(mp, tp, agbp, agino, flist, deleted, first_ino,
				 &rec);
				 &rec);
	if (error)
	if (error)
		goto error0;
		goto error0;
+1 −1
Original line number Original line Diff line number Diff line
@@ -90,7 +90,7 @@ xfs_difree(
	struct xfs_trans *tp,		/* transaction pointer */
	struct xfs_trans *tp,		/* transaction pointer */
	xfs_ino_t	inode,		/* inode to be freed */
	xfs_ino_t	inode,		/* inode to be freed */
	struct xfs_bmap_free *flist,	/* extents to free */
	struct xfs_bmap_free *flist,	/* extents to free */
	int		*delete,	/* set if inode cluster was deleted */
	int		*deleted,	/* set if inode cluster was deleted */
	xfs_ino_t	*first_ino);	/* first inode in deleted cluster */
	xfs_ino_t	*first_ino);	/* first inode in deleted cluster */


/*
/*
Loading