diff options
author | Dave Chinner <david@fromorbit.com> | 2014-03-13 04:13:05 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2014-03-13 04:13:05 -0400 |
commit | 5f44e4c185ec5a4a438841cbd4983d0c4a106a4a (patch) | |
tree | 894419c679250407eb7a76af9d1525c47226a085 /fs/xfs | |
parent | 49ae4b97d760d2e63394b96a7e14cbb43b9dc942 (diff) | |
parent | fe4c224aa1ffa4352849ac5f452de7132739bee2 (diff) |
Merge branch 'xfs-bug-fixes-for-3.15-2' into for-next
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/kmem.c | 21 | ||||
-rw-r--r-- | fs/xfs/xfs_aops.c | 81 | ||||
-rw-r--r-- | fs/xfs/xfs_buf.c | 11 | ||||
-rw-r--r-- | fs/xfs/xfs_ialloc.c | 12 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.c | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_symlink.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_buf.c | 11 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_resv.c | 22 |
8 files changed, 126 insertions, 39 deletions
diff --git a/fs/xfs/kmem.c b/fs/xfs/kmem.c index 66a36befc5c0..844e288b9576 100644 --- a/fs/xfs/kmem.c +++ b/fs/xfs/kmem.c | |||
@@ -65,12 +65,31 @@ kmem_alloc(size_t size, xfs_km_flags_t flags) | |||
65 | void * | 65 | void * |
66 | kmem_zalloc_large(size_t size, xfs_km_flags_t flags) | 66 | kmem_zalloc_large(size_t size, xfs_km_flags_t flags) |
67 | { | 67 | { |
68 | unsigned noio_flag = 0; | ||
68 | void *ptr; | 69 | void *ptr; |
70 | gfp_t lflags; | ||
69 | 71 | ||
70 | ptr = kmem_zalloc(size, flags | KM_MAYFAIL); | 72 | ptr = kmem_zalloc(size, flags | KM_MAYFAIL); |
71 | if (ptr) | 73 | if (ptr) |
72 | return ptr; | 74 | return ptr; |
73 | return vzalloc(size); | 75 | |
76 | /* | ||
77 | * __vmalloc() will allocate data pages and auxillary structures (e.g. | ||
78 | * pagetables) with GFP_KERNEL, yet we may be under GFP_NOFS context | ||
79 | * here. Hence we need to tell memory reclaim that we are in such a | ||
80 | * context via PF_MEMALLOC_NOIO to prevent memory reclaim re-entering | ||
81 | * the filesystem here and potentially deadlocking. | ||
82 | */ | ||
83 | if ((current->flags & PF_FSTRANS) || (flags & KM_NOFS)) | ||
84 | noio_flag = memalloc_noio_save(); | ||
85 | |||
86 | lflags = kmem_flags_convert(flags); | ||
87 | ptr = __vmalloc(size, lflags | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL); | ||
88 | |||
89 | if ((current->flags & PF_FSTRANS) || (flags & KM_NOFS)) | ||
90 | memalloc_noio_restore(noio_flag); | ||
91 | |||
92 | return ptr; | ||
74 | } | 93 | } |
75 | 94 | ||
76 | void | 95 | void |
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index ef62c6b6130a..98016b39b8af 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c | |||
@@ -632,38 +632,46 @@ xfs_map_at_offset( | |||
632 | } | 632 | } |
633 | 633 | ||
634 | /* | 634 | /* |
635 | * Test if a given page is suitable for writing as part of an unwritten | 635 | * Test if a given page contains at least one buffer of a given @type. |
636 | * or delayed allocate extent. | 636 | * If @check_all_buffers is true, then we walk all the buffers in the page to |
637 | * try to find one of the type passed in. If it is not set, then the caller only | ||
638 | * needs to check the first buffer on the page for a match. | ||
637 | */ | 639 | */ |
638 | STATIC int | 640 | STATIC bool |
639 | xfs_check_page_type( | 641 | xfs_check_page_type( |
640 | struct page *page, | 642 | struct page *page, |
641 | unsigned int type) | 643 | unsigned int type, |
644 | bool check_all_buffers) | ||
642 | { | 645 | { |
643 | if (PageWriteback(page)) | 646 | struct buffer_head *bh; |
644 | return 0; | 647 | struct buffer_head *head; |
645 | 648 | ||
646 | if (page->mapping && page_has_buffers(page)) { | 649 | if (PageWriteback(page)) |
647 | struct buffer_head *bh, *head; | 650 | return false; |
648 | int acceptable = 0; | 651 | if (!page->mapping) |
652 | return false; | ||
653 | if (!page_has_buffers(page)) | ||
654 | return false; | ||
649 | 655 | ||
650 | bh = head = page_buffers(page); | 656 | bh = head = page_buffers(page); |
651 | do { | 657 | do { |
652 | if (buffer_unwritten(bh)) | 658 | if (buffer_unwritten(bh)) { |
653 | acceptable += (type == XFS_IO_UNWRITTEN); | 659 | if (type == XFS_IO_UNWRITTEN) |
654 | else if (buffer_delay(bh)) | 660 | return true; |
655 | acceptable += (type == XFS_IO_DELALLOC); | 661 | } else if (buffer_delay(bh)) { |
656 | else if (buffer_dirty(bh) && buffer_mapped(bh)) | 662 | if (type == XFS_IO_DELALLOC); |
657 | acceptable += (type == XFS_IO_OVERWRITE); | 663 | return true; |
658 | else | 664 | } else if (buffer_dirty(bh) && buffer_mapped(bh)) { |
659 | break; | 665 | if (type == XFS_IO_OVERWRITE); |
660 | } while ((bh = bh->b_this_page) != head); | 666 | return true; |
667 | } | ||
661 | 668 | ||
662 | if (acceptable) | 669 | /* If we are only checking the first buffer, we are done now. */ |
663 | return 1; | 670 | if (!check_all_buffers) |
664 | } | 671 | break; |
672 | } while ((bh = bh->b_this_page) != head); | ||
665 | 673 | ||
666 | return 0; | 674 | return false; |
667 | } | 675 | } |
668 | 676 | ||
669 | /* | 677 | /* |
@@ -697,7 +705,7 @@ xfs_convert_page( | |||
697 | goto fail_unlock_page; | 705 | goto fail_unlock_page; |
698 | if (page->mapping != inode->i_mapping) | 706 | if (page->mapping != inode->i_mapping) |
699 | goto fail_unlock_page; | 707 | goto fail_unlock_page; |
700 | if (!xfs_check_page_type(page, (*ioendp)->io_type)) | 708 | if (!xfs_check_page_type(page, (*ioendp)->io_type, false)) |
701 | goto fail_unlock_page; | 709 | goto fail_unlock_page; |
702 | 710 | ||
703 | /* | 711 | /* |
@@ -742,6 +750,15 @@ xfs_convert_page( | |||
742 | p_offset = p_offset ? roundup(p_offset, len) : PAGE_CACHE_SIZE; | 750 | p_offset = p_offset ? roundup(p_offset, len) : PAGE_CACHE_SIZE; |
743 | page_dirty = p_offset / len; | 751 | page_dirty = p_offset / len; |
744 | 752 | ||
753 | /* | ||
754 | * The moment we find a buffer that doesn't match our current type | ||
755 | * specification or can't be written, abort the loop and start | ||
756 | * writeback. As per the above xfs_imap_valid() check, only | ||
757 | * xfs_vm_writepage() can handle partial page writeback fully - we are | ||
758 | * limited here to the buffers that are contiguous with the current | ||
759 | * ioend, and hence a buffer we can't write breaks that contiguity and | ||
760 | * we have to defer the rest of the IO to xfs_vm_writepage(). | ||
761 | */ | ||
745 | bh = head = page_buffers(page); | 762 | bh = head = page_buffers(page); |
746 | do { | 763 | do { |
747 | if (offset >= end_offset) | 764 | if (offset >= end_offset) |
@@ -750,7 +767,7 @@ xfs_convert_page( | |||
750 | uptodate = 0; | 767 | uptodate = 0; |
751 | if (!(PageUptodate(page) || buffer_uptodate(bh))) { | 768 | if (!(PageUptodate(page) || buffer_uptodate(bh))) { |
752 | done = 1; | 769 | done = 1; |
753 | continue; | 770 | break; |
754 | } | 771 | } |
755 | 772 | ||
756 | if (buffer_unwritten(bh) || buffer_delay(bh) || | 773 | if (buffer_unwritten(bh) || buffer_delay(bh) || |
@@ -762,10 +779,11 @@ xfs_convert_page( | |||
762 | else | 779 | else |
763 | type = XFS_IO_OVERWRITE; | 780 | type = XFS_IO_OVERWRITE; |
764 | 781 | ||
765 | if (!xfs_imap_valid(inode, imap, offset)) { | 782 | /* |
766 | done = 1; | 783 | * imap should always be valid because of the above |
767 | continue; | 784 | * partial page end_offset check on the imap. |
768 | } | 785 | */ |
786 | ASSERT(xfs_imap_valid(inode, imap, offset)); | ||
769 | 787 | ||
770 | lock_buffer(bh); | 788 | lock_buffer(bh); |
771 | if (type != XFS_IO_OVERWRITE) | 789 | if (type != XFS_IO_OVERWRITE) |
@@ -777,6 +795,7 @@ xfs_convert_page( | |||
777 | count++; | 795 | count++; |
778 | } else { | 796 | } else { |
779 | done = 1; | 797 | done = 1; |
798 | break; | ||
780 | } | 799 | } |
781 | } while (offset += len, (bh = bh->b_this_page) != head); | 800 | } while (offset += len, (bh = bh->b_this_page) != head); |
782 | 801 | ||
@@ -868,7 +887,7 @@ xfs_aops_discard_page( | |||
868 | struct buffer_head *bh, *head; | 887 | struct buffer_head *bh, *head; |
869 | loff_t offset = page_offset(page); | 888 | loff_t offset = page_offset(page); |
870 | 889 | ||
871 | if (!xfs_check_page_type(page, XFS_IO_DELALLOC)) | 890 | if (!xfs_check_page_type(page, XFS_IO_DELALLOC, true)) |
872 | goto out_invalidate; | 891 | goto out_invalidate; |
873 | 892 | ||
874 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | 893 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 9c061ef2b0d9..107f2fdfe41f 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -396,7 +396,17 @@ _xfs_buf_map_pages( | |||
396 | bp->b_addr = NULL; | 396 | bp->b_addr = NULL; |
397 | } else { | 397 | } else { |
398 | int retried = 0; | 398 | int retried = 0; |
399 | unsigned noio_flag; | ||
399 | 400 | ||
401 | /* | ||
402 | * vm_map_ram() will allocate auxillary structures (e.g. | ||
403 | * pagetables) with GFP_KERNEL, yet we are likely to be under | ||
404 | * GFP_NOFS context here. Hence we need to tell memory reclaim | ||
405 | * that we are in such a context via PF_MEMALLOC_NOIO to prevent | ||
406 | * memory reclaim re-entering the filesystem here and | ||
407 | * potentially deadlocking. | ||
408 | */ | ||
409 | noio_flag = memalloc_noio_save(); | ||
400 | do { | 410 | do { |
401 | bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count, | 411 | bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count, |
402 | -1, PAGE_KERNEL); | 412 | -1, PAGE_KERNEL); |
@@ -404,6 +414,7 @@ _xfs_buf_map_pages( | |||
404 | break; | 414 | break; |
405 | vm_unmap_aliases(); | 415 | vm_unmap_aliases(); |
406 | } while (retried++ <= 1); | 416 | } while (retried++ <= 1); |
417 | memalloc_noio_restore(noio_flag); | ||
407 | 418 | ||
408 | if (!bp->b_addr) | 419 | if (!bp->b_addr) |
409 | return -ENOMEM; | 420 | return -ENOMEM; |
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index 5959b3b4c7c9..8f711db61a0c 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
@@ -363,6 +363,18 @@ xfs_ialloc_ag_alloc( | |||
363 | args.minleft = args.mp->m_in_maxlevels - 1; | 363 | args.minleft = args.mp->m_in_maxlevels - 1; |
364 | if ((error = xfs_alloc_vextent(&args))) | 364 | if ((error = xfs_alloc_vextent(&args))) |
365 | return error; | 365 | return error; |
366 | |||
367 | /* | ||
368 | * This request might have dirtied the transaction if the AG can | ||
369 | * satisfy the request, but the exact block was not available. | ||
370 | * If the allocation did fail, subsequent requests will relax | ||
371 | * the exact agbno requirement and increase the alignment | ||
372 | * instead. It is critical that the total size of the request | ||
373 | * (len + alignment + slop) does not increase from this point | ||
374 | * on, so reset minalignslop to ensure it is not included in | ||
375 | * subsequent requests. | ||
376 | */ | ||
377 | args.minalignslop = 0; | ||
366 | } else | 378 | } else |
367 | args.fsbno = NULLFSBLOCK; | 379 | args.fsbno = NULLFSBLOCK; |
368 | 380 | ||
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index f96c05669a9e..993cb19e7d39 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -314,6 +314,9 @@ reread: | |||
314 | error = bp->b_error; | 314 | error = bp->b_error; |
315 | if (loud) | 315 | if (loud) |
316 | xfs_warn(mp, "SB validate failed with error %d.", error); | 316 | xfs_warn(mp, "SB validate failed with error %d.", error); |
317 | /* bad CRC means corrupted metadata */ | ||
318 | if (error == EFSBADCRC) | ||
319 | error = EFSCORRUPTED; | ||
317 | goto release_buf; | 320 | goto release_buf; |
318 | } | 321 | } |
319 | 322 | ||
diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 14e58f2c96bd..5fda18919d3b 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c | |||
@@ -80,6 +80,10 @@ xfs_readlink_bmap( | |||
80 | if (error) { | 80 | if (error) { |
81 | xfs_buf_ioerror_alert(bp, __func__); | 81 | xfs_buf_ioerror_alert(bp, __func__); |
82 | xfs_buf_relse(bp); | 82 | xfs_buf_relse(bp); |
83 | |||
84 | /* bad CRC means corrupted metadata */ | ||
85 | if (error == EFSBADCRC) | ||
86 | error = EFSCORRUPTED; | ||
83 | goto out; | 87 | goto out; |
84 | } | 88 | } |
85 | byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt); | 89 | byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt); |
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index 647b6f1d8923..b8eef0549f3f 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c | |||
@@ -275,6 +275,10 @@ xfs_trans_read_buf_map( | |||
275 | XFS_BUF_UNDONE(bp); | 275 | XFS_BUF_UNDONE(bp); |
276 | xfs_buf_stale(bp); | 276 | xfs_buf_stale(bp); |
277 | xfs_buf_relse(bp); | 277 | xfs_buf_relse(bp); |
278 | |||
279 | /* bad CRC means corrupted metadata */ | ||
280 | if (error == EFSBADCRC) | ||
281 | error = EFSCORRUPTED; | ||
278 | return error; | 282 | return error; |
279 | } | 283 | } |
280 | #ifdef DEBUG | 284 | #ifdef DEBUG |
@@ -338,6 +342,9 @@ xfs_trans_read_buf_map( | |||
338 | if (tp->t_flags & XFS_TRANS_DIRTY) | 342 | if (tp->t_flags & XFS_TRANS_DIRTY) |
339 | xfs_force_shutdown(tp->t_mountp, | 343 | xfs_force_shutdown(tp->t_mountp, |
340 | SHUTDOWN_META_IO_ERROR); | 344 | SHUTDOWN_META_IO_ERROR); |
345 | /* bad CRC means corrupted metadata */ | ||
346 | if (error == EFSBADCRC) | ||
347 | error = EFSCORRUPTED; | ||
341 | return error; | 348 | return error; |
342 | } | 349 | } |
343 | } | 350 | } |
@@ -375,6 +382,10 @@ xfs_trans_read_buf_map( | |||
375 | if (tp->t_flags & XFS_TRANS_DIRTY) | 382 | if (tp->t_flags & XFS_TRANS_DIRTY) |
376 | xfs_force_shutdown(tp->t_mountp, SHUTDOWN_META_IO_ERROR); | 383 | xfs_force_shutdown(tp->t_mountp, SHUTDOWN_META_IO_ERROR); |
377 | xfs_buf_relse(bp); | 384 | xfs_buf_relse(bp); |
385 | |||
386 | /* bad CRC means corrupted metadata */ | ||
387 | if (error == EFSBADCRC) | ||
388 | error = EFSCORRUPTED; | ||
378 | return error; | 389 | return error; |
379 | } | 390 | } |
380 | #ifdef DEBUG | 391 | #ifdef DEBUG |
diff --git a/fs/xfs/xfs_trans_resv.c b/fs/xfs/xfs_trans_resv.c index 8515b0449dc8..d2c8e4a6ee2a 100644 --- a/fs/xfs/xfs_trans_resv.c +++ b/fs/xfs/xfs_trans_resv.c | |||
@@ -81,20 +81,28 @@ xfs_calc_buf_res( | |||
81 | * on disk. Hence we need an inode reservation function that calculates all this | 81 | * on disk. Hence we need an inode reservation function that calculates all this |
82 | * correctly. So, we log: | 82 | * correctly. So, we log: |
83 | * | 83 | * |
84 | * - log op headers for object | 84 | * - 4 log op headers for object |
85 | * - for the ilf, the inode core and 2 forks | ||
85 | * - inode log format object | 86 | * - inode log format object |
86 | * - the entire inode contents (core + 2 forks) | 87 | * - the inode core |
87 | * - two bmap btree block headers | 88 | * - two inode forks containing bmap btree root blocks. |
89 | * - the btree data contained by both forks will fit into the inode size, | ||
90 | * hence when combined with the inode core above, we have a total of the | ||
91 | * actual inode size. | ||
92 | * - the BMBT headers need to be accounted separately, as they are | ||
93 | * additional to the records and pointers that fit inside the inode | ||
94 | * forks. | ||
88 | */ | 95 | */ |
89 | STATIC uint | 96 | STATIC uint |
90 | xfs_calc_inode_res( | 97 | xfs_calc_inode_res( |
91 | struct xfs_mount *mp, | 98 | struct xfs_mount *mp, |
92 | uint ninodes) | 99 | uint ninodes) |
93 | { | 100 | { |
94 | return ninodes * (sizeof(struct xlog_op_header) + | 101 | return ninodes * |
95 | sizeof(struct xfs_inode_log_format) + | 102 | (4 * sizeof(struct xlog_op_header) + |
96 | mp->m_sb.sb_inodesize + | 103 | sizeof(struct xfs_inode_log_format) + |
97 | 2 * XFS_BMBT_BLOCK_LEN(mp)); | 104 | mp->m_sb.sb_inodesize + |
105 | 2 * XFS_BMBT_BLOCK_LEN(mp)); | ||
98 | } | 106 | } |
99 | 107 | ||
100 | /* | 108 | /* |