Skip to content

Commit 0a4ebed

Browse files
committed
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() ...
2 parents 3b120ab + 9392557 commit 0a4ebed

31 files changed

+995
-536
lines changed

fs/ocfs2/alloc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5699,7 +5699,7 @@ int ocfs2_remove_btree_range(struct inode *inode,
56995699
OCFS2_JOURNAL_ACCESS_WRITE);
57005700
if (ret) {
57015701
mlog_errno(ret);
5702-
goto out;
5702+
goto out_commit;
57035703
}
57045704

57055705
dquot_free_space_nodirty(inode,

fs/ocfs2/aops.c

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,15 @@ static int ocfs2_readpage(struct file *file, struct page *page)
290290
}
291291

292292
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+
*/
293297
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);
294302
goto out_inode_unlock;
295303
}
296304

@@ -563,13 +571,23 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,
563571
{
564572
struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
565573
int level;
574+
wait_queue_head_t *wq = ocfs2_ioend_wq(inode);
566575

567576
/* this io's submitter should not have unlocked this before we could */
568577
BUG_ON(!ocfs2_iocb_is_rw_locked(iocb));
569578

570579
if (ocfs2_iocb_is_sem_locked(iocb))
571580
ocfs2_iocb_clear_sem_locked(iocb);
572581

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+
573591
ocfs2_iocb_clear_rw_locked(iocb);
574592

575593
level = ocfs2_iocb_rw_locked_level(iocb);
@@ -862,6 +880,12 @@ struct ocfs2_write_ctxt {
862880
struct page *w_pages[OCFS2_MAX_CTXT_PAGES];
863881
struct page *w_target_page;
864882

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+
865889
/*
866890
* ocfs2_write_end() uses this to know what the real range to
867891
* write in the target should be.
@@ -895,6 +919,24 @@ void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages)
895919

896920
static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
897921
{
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+
}
898940
ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages);
899941

900942
brelse(wc->w_di_bh);
@@ -1132,20 +1174,17 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
11321174
*/
11331175
lock_page(mmap_page);
11341176

1177+
/* Exit and let the caller retry */
11351178
if (mmap_page->mapping != mapping) {
1179+
WARN_ON(mmap_page->mapping);
11361180
unlock_page(mmap_page);
1137-
/*
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);
1181+
ret = -EAGAIN;
11441182
goto out;
11451183
}
11461184

11471185
page_cache_get(mmap_page);
11481186
wc->w_pages[i] = mmap_page;
1187+
wc->w_target_locked = true;
11491188
} else {
11501189
wc->w_pages[i] = find_or_create_page(mapping, index,
11511190
GFP_NOFS);
@@ -1160,6 +1199,8 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
11601199
wc->w_target_page = wc->w_pages[i];
11611200
}
11621201
out:
1202+
if (ret)
1203+
wc->w_target_locked = false;
11631204
return ret;
11641205
}
11651206

@@ -1817,11 +1858,23 @@ int ocfs2_write_begin_nolock(struct file *filp,
18171858
*/
18181859
ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos, len,
18191860
cluster_of_pages, mmap_page);
1820-
if (ret) {
1861+
if (ret && ret != -EAGAIN) {
18211862
mlog_errno(ret);
18221863
goto out_quota;
18231864
}
18241865

1866+
/*
1867+
* ocfs2_grab_pages_for_write() returns -EAGAIN if it could not lock
1868+
* the target page. In this case, we exit with no error and no target
1869+
* page. This will trigger the caller, page_mkwrite(), to re-try
1870+
* the operation.
1871+
*/
1872+
if (ret == -EAGAIN) {
1873+
BUG_ON(wc->w_target_page);
1874+
ret = 0;
1875+
goto out_quota;
1876+
}
1877+
18251878
ret = ocfs2_write_cluster_by_desc(mapping, data_ac, meta_ac, wc, pos,
18261879
len);
18271880
if (ret) {

fs/ocfs2/aops.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ enum ocfs2_iocb_lock_bits {
7878
OCFS2_IOCB_RW_LOCK = 0,
7979
OCFS2_IOCB_RW_LOCK_LEVEL,
8080
OCFS2_IOCB_SEM,
81+
OCFS2_IOCB_UNALIGNED_IO,
8182
OCFS2_IOCB_NUM_LOCKS
8283
};
8384

@@ -91,4 +92,17 @@ enum ocfs2_iocb_lock_bits {
9192
clear_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
9293
#define ocfs2_iocb_is_sem_locked(iocb) \
9394
test_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
95+
96+
#define ocfs2_iocb_set_unaligned_aio(iocb) \
97+
set_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private)
98+
#define ocfs2_iocb_clear_unaligned_aio(iocb) \
99+
clear_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private)
100+
#define ocfs2_iocb_is_unaligned_aio(iocb) \
101+
test_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private)
102+
103+
#define OCFS2_IOEND_WQ_HASH_SZ 37
104+
#define ocfs2_ioend_wq(v) (&ocfs2__ioend_wq[((unsigned long)(v)) %\
105+
OCFS2_IOEND_WQ_HASH_SZ])
106+
extern wait_queue_head_t ocfs2__ioend_wq[OCFS2_IOEND_WQ_HASH_SZ];
107+
94108
#endif /* OCFS2_FILE_H */

0 commit comments

Comments
 (0)