diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-12-01 17:55:34 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-12-01 17:55:34 -0500 |
| commit | 0a4ebed781dbb9ecbfef2374d29da1ab3b1a63f3 (patch) | |
| tree | ab171047c0b1bab2d423e85106f84fdf7b52ac7d | |
| parent | 3b120ab76225592e9c267086fa4dfa3ce5a075fe (diff) | |
| parent | 939255798a468e1a92f03546de6e87be7b491e57 (diff) | |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2: (31 commits)
ocfs2: avoid unaligned access to dqc_bitmap
ocfs2: Use filemap_write_and_wait() instead of write_inode_now()
ocfs2: honor O_(D)SYNC flag in fallocate
ocfs2: Add a missing journal credit in ocfs2_link_credits() -v2
ocfs2: send correct UUID to cleancache initialization
ocfs2: Commit transactions in error cases -v2
ocfs2: make direntry invalid when deleting it
fs/ocfs2/dlm/dlmlock.c: free kmem_cache_zalloc'd data using kmem_cache_free
ocfs2: Avoid livelock in ocfs2_readpage()
ocfs2: serialize unaligned aio
ocfs2: Implement llseek()
ocfs2: Fix ocfs2_page_mkwrite()
ocfs2: Add comment about orphan scanning
ocfs2: Clean up messages in the fs
ocfs2/cluster: Cluster up now includes network connections too
ocfs2/cluster: Add new function o2net_fill_node_map()
ocfs2/cluster: Fix output in file elapsed_time_in_ms
ocfs2/dlm: dlmlock_remote() needs to account for remastery
ocfs2/dlm: Take inflight reference count for remotely mastered resources too
ocfs2/dlm: Cleanup dlm_wait_for_node_death() and dlm_wait_for_node_recovery()
...
31 files changed, 995 insertions, 536 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index ed553c60de82..3165aebb43c8 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
| @@ -5699,7 +5699,7 @@ int ocfs2_remove_btree_range(struct inode *inode, | |||
| 5699 | OCFS2_JOURNAL_ACCESS_WRITE); | 5699 | OCFS2_JOURNAL_ACCESS_WRITE); |
| 5700 | if (ret) { | 5700 | if (ret) { |
| 5701 | mlog_errno(ret); | 5701 | mlog_errno(ret); |
| 5702 | goto out; | 5702 | goto out_commit; |
| 5703 | } | 5703 | } |
| 5704 | 5704 | ||
| 5705 | dquot_free_space_nodirty(inode, | 5705 | dquot_free_space_nodirty(inode, |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index c1efe939c774..78b68af3b0e3 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
| @@ -290,7 +290,15 @@ static int ocfs2_readpage(struct file *file, struct page *page) | |||
| 290 | } | 290 | } |
| 291 | 291 | ||
| 292 | if (down_read_trylock(&oi->ip_alloc_sem) == 0) { | 292 | if (down_read_trylock(&oi->ip_alloc_sem) == 0) { |
| 293 | /* | ||
| 294 | * Unlock the page and cycle ip_alloc_sem so that we don't | ||
| 295 | * busyloop waiting for ip_alloc_sem to unlock | ||
| 296 | */ | ||
| 293 | ret = AOP_TRUNCATED_PAGE; | 297 | ret = AOP_TRUNCATED_PAGE; |
| 298 | unlock_page(page); | ||
| 299 | unlock = 0; | ||
| 300 | down_read(&oi->ip_alloc_sem); | ||
| 301 | up_read(&oi->ip_alloc_sem); | ||
| 294 | goto out_inode_unlock; | 302 | goto out_inode_unlock; |
| 295 | } | 303 | } |
| 296 | 304 | ||
| @@ -563,6 +571,7 @@ static void ocfs2_dio_end_io(struct kiocb *iocb, | |||
| 563 | { | 571 | { |
| 564 | struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode; | 572 | struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode; |
| 565 | int level; | 573 | int level; |
| 574 | wait_queue_head_t *wq = ocfs2_ioend_wq(inode); | ||
| 566 | 575 | ||
| 567 | /* this io's submitter should not have unlocked this before we could */ | 576 | /* this io's submitter should not have unlocked this before we could */ |
| 568 | BUG_ON(!ocfs2_iocb_is_rw_locked(iocb)); | 577 | BUG_ON(!ocfs2_iocb_is_rw_locked(iocb)); |
| @@ -570,6 +579,15 @@ static void ocfs2_dio_end_io(struct kiocb *iocb, | |||
| 570 | if (ocfs2_iocb_is_sem_locked(iocb)) | 579 | if (ocfs2_iocb_is_sem_locked(iocb)) |
| 571 | ocfs2_iocb_clear_sem_locked(iocb); | 580 | ocfs2_iocb_clear_sem_locked(iocb); |
| 572 | 581 | ||
| 582 | if (ocfs2_iocb_is_unaligned_aio(iocb)) { | ||
| 583 | ocfs2_iocb_clear_unaligned_aio(iocb); | ||
| 584 | |||
| 585 | if (atomic_dec_and_test(&OCFS2_I(inode)->ip_unaligned_aio) && | ||
| 586 | waitqueue_active(wq)) { | ||
| 587 | wake_up_all(wq); | ||
| 588 | } | ||
| 589 | } | ||
| 590 | |||
| 573 | ocfs2_iocb_clear_rw_locked(iocb); | 591 | ocfs2_iocb_clear_rw_locked(iocb); |
| 574 | 592 | ||
| 575 | level = ocfs2_iocb_rw_locked_level(iocb); | 593 | level = ocfs2_iocb_rw_locked_level(iocb); |
| @@ -863,6 +881,12 @@ struct ocfs2_write_ctxt { | |||
| 863 | struct page *w_target_page; | 881 | struct page *w_target_page; |
| 864 | 882 | ||
| 865 | /* | 883 | /* |
| 884 | * w_target_locked is used for page_mkwrite path indicating no unlocking | ||
| 885 | * against w_target_page in ocfs2_write_end_nolock. | ||
| 886 | */ | ||
| 887 | unsigned int w_target_locked:1; | ||
| 888 | |||
| 889 | /* | ||
| 866 | * ocfs2_write_end() uses this to know what the real range to | 890 | * ocfs2_write_end() uses this to know what the real range to |
| 867 | * write in the target should be. | 891 | * write in the target should be. |
| 868 | */ | 892 | */ |
| @@ -895,6 +919,24 @@ void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages) | |||
| 895 | 919 | ||
| 896 | static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc) | 920 | static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc) |
| 897 | { | 921 | { |
| 922 | int i; | ||
| 923 | |||
| 924 | /* | ||
| 925 | * w_target_locked is only set to true in the page_mkwrite() case. | ||
| 926 | * The intent is to allow us to lock the target page from write_begin() | ||
| 927 | * to write_end(). The caller must hold a ref on w_target_page. | ||
| 928 | */ | ||
| 929 | if (wc->w_target_locked) { | ||
| 930 | BUG_ON(!wc->w_target_page); | ||
| 931 | for (i = 0; i < wc->w_num_pages; i++) { | ||
| 932 | if (wc->w_target_page == wc->w_pages[i]) { | ||
| 933 | wc->w_pages[i] = NULL; | ||
| 934 | break; | ||
| 935 | } | ||
| 936 | } | ||
| 937 | mark_page_accessed(wc->w_target_page); | ||
| 938 | page_cache_release(wc->w_target_page); | ||
| 939 | } | ||
| 898 | ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages); | 940 | ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages); |
| 899 | 941 | ||
| 900 | brelse(wc->w_di_bh); | 942 | brelse(wc->w_di_bh); |
| @@ -1132,20 +1174,17 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping, | |||
| 1132 | */ | 1174 | */ |
| 1133 | lock_page(mmap_page); | 1175 | lock_page(mmap_page); |
| 1134 | 1176 | ||
| 1177 | /* Exit and let the caller retry */ | ||
| 1135 | if (mmap_page->mapping != mapping) { | 1178 | if (mmap_page->mapping != mapping) { |
| 1179 | WARN_ON(mmap_page->mapping); | ||
| 1136 | unlock_page(mmap_page); | 1180 | unlock_page(mmap_page); |
| 1137 | /* | 1181 | ret = -EAGAIN; |
| 1138 | * Sanity check - the locking in | ||
| 1139 | * ocfs2_pagemkwrite() should ensure | ||
| 1140 | * that this code doesn't trigger. | ||
| 1141 | */ | ||
| 1142 | ret = -EINVAL; | ||
| 1143 | mlog_errno(ret); | ||
| 1144 | goto out; | 1182 | goto out; |
| 1145 | } | 1183 | } |
| 1146 | 1184 | ||
| 1147 | page_cache_get(mmap_page); | 1185 | page_cache_get(mmap_page); |
| 1148 | wc->w_pages[i] = mmap_page; | 1186 | wc->w_pages[i] = mmap_page; |
| 1187 | wc->w_target_locked = true; | ||
| 1149 | } else { | 1188 | } else { |
| 1150 | wc->w_pages[i] = find_or_create_page(mapping, index, | 1189 | wc->w_pages[i] = find_or_create_page(mapping, index, |
| 1151 | GFP_NOFS); | 1190 | GFP_NOFS); |
| @@ -1160,6 +1199,8 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping, | |||
| 1160 | wc->w_target_page = wc->w_pages[i]; | 1199 | wc->w_target_page = wc->w_pages[i]; |
| 1161 | } | 1200 | } |
| 1162 | out: | 1201 | out: |
| 1202 | if (ret) | ||
| 1203 | wc->w_target_locked = false; | ||
| 1163 | return ret; | 1204 | return ret; |
| 1164 | } | 1205 | } |
| 1165 | 1206 | ||
| @@ -1817,11 +1858,23 @@ try_again: | |||
