Ocfs2: Teach 'coherency=full' O_DIRECT writes to correctly up_read i_alloc_sem.

Due to newly-introduced 'coherency=full' O_DIRECT writes also takes the EX
rw_lock like buffered writes did(rw_level == 1), it turns out messing the
usage of 'level' in ocfs2_dio_end_io() up, which caused i_alloc_sem being
failed to get up_read'd correctly.

This patch tries to teach ocfs2_dio_end_io to understand well on all locking
stuffs by explicitly introducing a new bit for i_alloc_sem in iocb's private
data, just like what we did for rw_lock.

Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>

authored by Tristan Ye and committed by Joel Becker 39c99f12 388c4bcb

+39 -6
+5 -2
fs/ocfs2/aops.c
··· 573 /* this io's submitter should not have unlocked this before we could */ 574 BUG_ON(!ocfs2_iocb_is_rw_locked(iocb)); 575 576 ocfs2_iocb_clear_rw_locked(iocb); 577 578 level = ocfs2_iocb_rw_locked_level(iocb); 579 - if (!level) 580 - up_read(&inode->i_alloc_sem); 581 ocfs2_rw_unlock(inode, level); 582 583 if (is_async)
··· 573 /* this io's submitter should not have unlocked this before we could */ 574 BUG_ON(!ocfs2_iocb_is_rw_locked(iocb)); 575 576 + if (ocfs2_iocb_is_sem_locked(iocb)) { 577 + up_read(&inode->i_alloc_sem); 578 + ocfs2_iocb_clear_sem_locked(iocb); 579 + } 580 + 581 ocfs2_iocb_clear_rw_locked(iocb); 582 583 level = ocfs2_iocb_rw_locked_level(iocb); 584 ocfs2_rw_unlock(inode, level); 585 586 if (is_async)
+21 -2
fs/ocfs2/aops.h
··· 68 else 69 clear_bit(1, (unsigned long *)&iocb->private); 70 } 71 #define ocfs2_iocb_clear_rw_locked(iocb) \ 72 - clear_bit(0, (unsigned long *)&iocb->private) 73 #define ocfs2_iocb_rw_locked_level(iocb) \ 74 - test_bit(1, (unsigned long *)&iocb->private) 75 #endif /* OCFS2_FILE_H */
··· 68 else 69 clear_bit(1, (unsigned long *)&iocb->private); 70 } 71 + 72 + /* 73 + * Using a named enum representing lock types in terms of #N bit stored in 74 + * iocb->private, which is going to be used for communication bewteen 75 + * ocfs2_dio_end_io() and ocfs2_file_aio_write/read(). 76 + */ 77 + enum ocfs2_iocb_lock_bits { 78 + OCFS2_IOCB_RW_LOCK = 0, 79 + OCFS2_IOCB_RW_LOCK_LEVEL, 80 + OCFS2_IOCB_SEM, 81 + OCFS2_IOCB_NUM_LOCKS 82 + }; 83 + 84 #define ocfs2_iocb_clear_rw_locked(iocb) \ 85 + clear_bit(OCFS2_IOCB_RW_LOCK, (unsigned long *)&iocb->private) 86 #define ocfs2_iocb_rw_locked_level(iocb) \ 87 + test_bit(OCFS2_IOCB_RW_LOCK_LEVEL, (unsigned long *)&iocb->private) 88 + #define ocfs2_iocb_set_sem_locked(iocb) \ 89 + set_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private) 90 + #define ocfs2_iocb_clear_sem_locked(iocb) \ 91 + clear_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private) 92 + #define ocfs2_iocb_is_sem_locked(iocb) \ 93 + test_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private) 94 #endif /* OCFS2_FILE_H */
+13 -2
fs/ocfs2/file.c
··· 2241 2242 mutex_lock(&inode->i_mutex); 2243 2244 relock: 2245 /* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */ 2246 if (direct_io) { 2247 down_read(&inode->i_alloc_sem); 2248 have_alloc_sem = 1; 2249 } 2250 2251 /* ··· 2386 ocfs2_rw_unlock(inode, rw_level); 2387 2388 out_sems: 2389 - if (have_alloc_sem) 2390 up_read(&inode->i_alloc_sem); 2391 2392 mutex_unlock(&inode->i_mutex); 2393 ··· 2533 goto bail; 2534 } 2535 2536 /* 2537 * buffered reads protect themselves in ->readpage(). O_DIRECT reads 2538 * need locks to protect pending reads from racing with truncate. ··· 2542 if (filp->f_flags & O_DIRECT) { 2543 down_read(&inode->i_alloc_sem); 2544 have_alloc_sem = 1; 2545 2546 ret = ocfs2_rw_lock(inode, 0); 2547 if (ret < 0) { ··· 2584 } 2585 2586 bail: 2587 - if (have_alloc_sem) 2588 up_read(&inode->i_alloc_sem); 2589 if (rw_level != -1) 2590 ocfs2_rw_unlock(inode, rw_level); 2591 mlog_exit(ret);
··· 2241 2242 mutex_lock(&inode->i_mutex); 2243 2244 + ocfs2_iocb_clear_sem_locked(iocb); 2245 + 2246 relock: 2247 /* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */ 2248 if (direct_io) { 2249 down_read(&inode->i_alloc_sem); 2250 have_alloc_sem = 1; 2251 + /* communicate with ocfs2_dio_end_io */ 2252 + ocfs2_iocb_set_sem_locked(iocb); 2253 } 2254 2255 /* ··· 2382 ocfs2_rw_unlock(inode, rw_level); 2383 2384 out_sems: 2385 + if (have_alloc_sem) { 2386 up_read(&inode->i_alloc_sem); 2387 + ocfs2_iocb_clear_sem_locked(iocb); 2388 + } 2389 2390 mutex_unlock(&inode->i_mutex); 2391 ··· 2527 goto bail; 2528 } 2529 2530 + ocfs2_iocb_clear_sem_locked(iocb); 2531 + 2532 /* 2533 * buffered reads protect themselves in ->readpage(). O_DIRECT reads 2534 * need locks to protect pending reads from racing with truncate. ··· 2534 if (filp->f_flags & O_DIRECT) { 2535 down_read(&inode->i_alloc_sem); 2536 have_alloc_sem = 1; 2537 + ocfs2_iocb_set_sem_locked(iocb); 2538 2539 ret = ocfs2_rw_lock(inode, 0); 2540 if (ret < 0) { ··· 2575 } 2576 2577 bail: 2578 + if (have_alloc_sem) { 2579 up_read(&inode->i_alloc_sem); 2580 + ocfs2_iocb_clear_sem_locked(iocb); 2581 + } 2582 if (rw_level != -1) 2583 ocfs2_rw_unlock(inode, rw_level); 2584 mlog_exit(ret);