diff options
author | Dave Chinner <david@fromorbit.com> | 2014-09-23 08:55:51 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2014-09-23 08:55:51 -0400 |
commit | 33044dc408e6e6bb7f270c0a2e12598ef5592987 (patch) | |
tree | 67dedd3461599e28a95e298db436bc3fc4139d4f /fs | |
parent | f6d31f4b0462898896ba68e491662958ce37d095 (diff) | |
parent | 2ebff7bbd785c86e12956388b9e6f6bb8ea5d21e (diff) |
Merge branch 'xfs-misc-fixes-for-3.18-2' into for-next
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/libxfs/xfs_da_format.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap_util.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_buf_item.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_icache.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_iops.c | 30 | ||||
-rw-r--r-- | fs/xfs/xfs_log_cil.c | 47 | ||||
-rw-r--r-- | fs/xfs/xfs_rtalloc.c | 2 |
7 files changed, 71 insertions, 14 deletions
diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index c9aee52a37e2..7e42fdfd2f1d 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c | |||
@@ -270,7 +270,6 @@ xfs_dir3_data_get_ftype( | |||
270 | { | 270 | { |
271 | __uint8_t ftype = dep->name[dep->namelen]; | 271 | __uint8_t ftype = dep->name[dep->namelen]; |
272 | 272 | ||
273 | ASSERT(ftype < XFS_DIR3_FT_MAX); | ||
274 | if (ftype >= XFS_DIR3_FT_MAX) | 273 | if (ftype >= XFS_DIR3_FT_MAX) |
275 | return XFS_DIR3_FT_UNKNOWN; | 274 | return XFS_DIR3_FT_UNKNOWN; |
276 | return ftype; | 275 | return ftype; |
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 809ae7d395c3..d8b77b5bf4d9 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c | |||
@@ -1646,7 +1646,7 @@ xfs_swap_extents_check_format( | |||
1646 | return 0; | 1646 | return 0; |
1647 | } | 1647 | } |
1648 | 1648 | ||
1649 | int | 1649 | static int |
1650 | xfs_swap_extent_flush( | 1650 | xfs_swap_extent_flush( |
1651 | struct xfs_inode *ip) | 1651 | struct xfs_inode *ip) |
1652 | { | 1652 | { |
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 76007deed31f..30fa5db9aea8 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
@@ -501,7 +501,7 @@ xfs_buf_item_unpin( | |||
501 | * buffer being bad.. | 501 | * buffer being bad.. |
502 | */ | 502 | */ |
503 | 503 | ||
504 | DEFINE_RATELIMIT_STATE(xfs_buf_write_fail_rl_state, 30 * HZ, 10); | 504 | static DEFINE_RATELIMIT_STATE(xfs_buf_write_fail_rl_state, 30 * HZ, 10); |
505 | 505 | ||
506 | STATIC uint | 506 | STATIC uint |
507 | xfs_buf_item_push( | 507 | xfs_buf_item_push( |
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 981b2cf51985..b45f7b27b5df 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include "xfs_trace.h" | 33 | #include "xfs_trace.h" |
34 | #include "xfs_icache.h" | 34 | #include "xfs_icache.h" |
35 | #include "xfs_bmap_util.h" | 35 | #include "xfs_bmap_util.h" |
36 | #include "xfs_quota.h" | ||
37 | #include "xfs_dquot_item.h" | 36 | #include "xfs_dquot_item.h" |
38 | #include "xfs_dquot.h" | 37 | #include "xfs_dquot.h" |
39 | 38 | ||
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 72129493e9d3..ec6dcdc181ee 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
@@ -849,6 +849,36 @@ xfs_setattr_size( | |||
849 | return error; | 849 | return error; |
850 | truncate_setsize(inode, newsize); | 850 | truncate_setsize(inode, newsize); |
851 | 851 | ||
852 | /* | ||
853 | * The "we can't serialise against page faults" pain gets worse. | ||
854 | * | ||
855 | * If the file is mapped then we have to clean the page at the old EOF | ||
856 | * when extending the file. Extending the file can expose changes the | ||
857 | * underlying page mapping (e.g. from beyond EOF to a hole or | ||
858 | * unwritten), and so on the next attempt to write to that page we need | ||
859 | * to remap it for write. i.e. we need .page_mkwrite() to be called. | ||
860 | * Hence we need to clean the page to clean the pte and so a new write | ||
861 | * fault will be triggered appropriately. | ||
862 | * | ||
863 | * If we do it before we change the inode size, then we can race with a | ||
864 | * page fault that maps the page with exactly the same problem. If we do | ||
865 | * it after we change the file size, then a new page fault can come in | ||
866 | * and allocate space before we've run the rest of the truncate | ||
867 | * transaction. That's kinda grotesque, but it's better than have data | ||
868 | * over a hole, and so that's the lesser evil that has been chosen here. | ||
869 | * | ||
870 | * The real solution, however, is to have some mechanism for locking out | ||
871 | * page faults while a truncate is in progress. | ||
872 | */ | ||
873 | if (newsize > oldsize && mapping_mapped(VFS_I(ip)->i_mapping)) { | ||
874 | error = filemap_write_and_wait_range( | ||
875 | VFS_I(ip)->i_mapping, | ||
876 | round_down(oldsize, PAGE_CACHE_SIZE), | ||
877 | round_up(oldsize, PAGE_CACHE_SIZE) - 1); | ||
878 | if (error) | ||
879 | return error; | ||
880 | } | ||
881 | |||
852 | tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE); | 882 | tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE); |
853 | error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0); | 883 | error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0); |
854 | if (error) | 884 | if (error) |
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index f6b79e5325dd..f506c457011e 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c | |||
@@ -463,12 +463,40 @@ xlog_cil_push( | |||
463 | spin_unlock(&cil->xc_push_lock); | 463 | spin_unlock(&cil->xc_push_lock); |
464 | goto out_skip; | 464 | goto out_skip; |
465 | } | 465 | } |
466 | spin_unlock(&cil->xc_push_lock); | ||
467 | 466 | ||
468 | 467 | ||
469 | /* check for a previously pushed seqeunce */ | 468 | /* check for a previously pushed seqeunce */ |
470 | if (push_seq < cil->xc_ctx->sequence) | 469 | if (push_seq < cil->xc_ctx->sequence) { |
470 | spin_unlock(&cil->xc_push_lock); | ||
471 | goto out_skip; | 471 | goto out_skip; |
472 | } | ||
473 | |||
474 | /* | ||
475 | * We are now going to push this context, so add it to the committing | ||
476 | * list before we do anything else. This ensures that anyone waiting on | ||
477 | * this push can easily detect the difference between a "push in | ||
478 | * progress" and "CIL is empty, nothing to do". | ||
479 | * | ||
480 | * IOWs, a wait loop can now check for: | ||
481 | * the current sequence not being found on the committing list; | ||
482 | * an empty CIL; and | ||
483 | * an unchanged sequence number | ||
484 | * to detect a push that had nothing to do and therefore does not need | ||
485 | * waiting on. If the CIL is not empty, we get put on the committing | ||
486 | * list before emptying the CIL and bumping the sequence number. Hence | ||
487 | * an empty CIL and an unchanged sequence number means we jumped out | ||
488 | * above after doing nothing. | ||
489 | * | ||
490 | * Hence the waiter will either find the commit sequence on the | ||
491 | * committing list or the sequence number will be unchanged and the CIL | ||
492 | * still dirty. In that latter case, the push has not yet started, and | ||
493 | * so the waiter will have to continue trying to check the CIL | ||
494 | * committing list until it is found. In extreme cases of delay, the | ||
495 | * sequence may fully commit between the attempts the wait makes to wait | ||
496 | * on the commit sequence. | ||
497 | */ | ||
498 | list_add(&ctx->committing, &cil->xc_committing); | ||
499 | spin_unlock(&cil->xc_push_lock); | ||
472 | 500 | ||
473 | /* | 501 | /* |
474 | * pull all the log vectors off the items in the CIL, and | 502 | * pull all the log vectors off the items in the CIL, and |
@@ -532,7 +560,6 @@ xlog_cil_push( | |||
532 | */ | 560 | */ |
533 | spin_lock(&cil->xc_push_lock); | 561 | spin_lock(&cil->xc_push_lock); |
534 | cil->xc_current_sequence = new_ctx->sequence; | 562 | cil->xc_current_sequence = new_ctx->sequence; |
535 | list_add(&ctx->committing, &cil->xc_committing); | ||
536 | spin_unlock(&cil->xc_push_lock); | 563 | spin_unlock(&cil->xc_push_lock); |
537 | up_write(&cil->xc_ctx_lock); | 564 | up_write(&cil->xc_ctx_lock); |
538 | 565 | ||
@@ -855,13 +882,15 @@ restart: | |||
855 | * Hence by the time we have got here it our sequence may not have been | 882 | * Hence by the time we have got here it our sequence may not have been |
856 | * pushed yet. This is true if the current sequence still matches the | 883 | * pushed yet. This is true if the current sequence still matches the |
857 | * push sequence after the above wait loop and the CIL still contains | 884 | * push sequence after the above wait loop and the CIL still contains |
858 | * dirty objects. | 885 | * dirty objects. This is guaranteed by the push code first adding the |
886 | * context to the committing list before emptying the CIL. | ||
859 | * | 887 | * |
860 | * When the push occurs, it will empty the CIL and atomically increment | 888 | * Hence if we don't find the context in the committing list and the |
861 | * the currect sequence past the push sequence and move it into the | 889 | * current sequence number is unchanged then the CIL contents are |
862 | * committing list. Of course, if the CIL is clean at the time of the | 890 | * significant. If the CIL is empty, if means there was nothing to push |
863 | * push, it won't have pushed the CIL at all, so in that case we should | 891 | * and that means there is nothing to wait for. If the CIL is not empty, |
864 | * try the push for this sequence again from the start just in case. | 892 | * it means we haven't yet started the push, because if it had started |
893 | * we would have found the context on the committing list. | ||
865 | */ | 894 | */ |
866 | if (sequence == cil->xc_current_sequence && | 895 | if (sequence == cil->xc_current_sequence && |
867 | !list_empty(&cil->xc_cil)) { | 896 | !list_empty(&cil->xc_cil)) { |
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index d1160cce5dad..d45aebe04dde 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c | |||
@@ -46,7 +46,7 @@ | |||
46 | * Keeps track of a current summary block, so we don't keep reading | 46 | * Keeps track of a current summary block, so we don't keep reading |
47 | * it from the buffer cache. | 47 | * it from the buffer cache. |
48 | */ | 48 | */ |
49 | int | 49 | static int |
50 | xfs_rtget_summary( | 50 | xfs_rtget_summary( |
51 | xfs_mount_t *mp, /* file system mount structure */ | 51 | xfs_mount_t *mp, /* file system mount structure */ |
52 | xfs_trans_t *tp, /* transaction pointer */ | 52 | xfs_trans_t *tp, /* transaction pointer */ |