diff options
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/aops.c | 9 | ||||
-rw-r--r-- | fs/ocfs2/aops.h | 13 | ||||
-rw-r--r-- | fs/ocfs2/file.c | 4 |
3 files changed, 19 insertions, 7 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index b74971e19d54..56963e6c46c0 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -522,12 +522,17 @@ static void ocfs2_dio_end_io(struct kiocb *iocb, | |||
522 | void *private) | 522 | void *private) |
523 | { | 523 | { |
524 | struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode; | 524 | struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode; |
525 | int level; | ||
525 | 526 | ||
526 | /* this io's submitter should not have unlocked this before we could */ | 527 | /* this io's submitter should not have unlocked this before we could */ |
527 | BUG_ON(!ocfs2_iocb_is_rw_locked(iocb)); | 528 | BUG_ON(!ocfs2_iocb_is_rw_locked(iocb)); |
529 | |||
528 | ocfs2_iocb_clear_rw_locked(iocb); | 530 | ocfs2_iocb_clear_rw_locked(iocb); |
529 | up_read(&inode->i_alloc_sem); | 531 | |
530 | ocfs2_rw_unlock(inode, 0); | 532 | level = ocfs2_iocb_rw_locked_level(iocb); |
533 | if (!level) | ||
534 | up_read(&inode->i_alloc_sem); | ||
535 | ocfs2_rw_unlock(inode, level); | ||
531 | } | 536 | } |
532 | 537 | ||
533 | /* | 538 | /* |
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h index 1b4ba5356a42..45821d479b5a 100644 --- a/fs/ocfs2/aops.h +++ b/fs/ocfs2/aops.h | |||
@@ -97,9 +97,16 @@ int ocfs2_map_and_write_splice_data(struct inode *inode, | |||
97 | /* all ocfs2_dio_end_io()'s fault */ | 97 | /* all ocfs2_dio_end_io()'s fault */ |
98 | #define ocfs2_iocb_is_rw_locked(iocb) \ | 98 | #define ocfs2_iocb_is_rw_locked(iocb) \ |
99 | test_bit(0, (unsigned long *)&iocb->private) | 99 | test_bit(0, (unsigned long *)&iocb->private) |
100 | #define ocfs2_iocb_set_rw_locked(iocb) \ | 100 | static inline void ocfs2_iocb_set_rw_locked(struct kiocb *iocb, int level) |
101 | set_bit(0, (unsigned long *)&iocb->private) | 101 | { |
102 | set_bit(0, (unsigned long *)&iocb->private); | ||
103 | if (level) | ||
104 | set_bit(1, (unsigned long *)&iocb->private); | ||
105 | else | ||
106 | clear_bit(1, (unsigned long *)&iocb->private); | ||
107 | } | ||
102 | #define ocfs2_iocb_clear_rw_locked(iocb) \ | 108 | #define ocfs2_iocb_clear_rw_locked(iocb) \ |
103 | clear_bit(0, (unsigned long *)&iocb->private) | 109 | clear_bit(0, (unsigned long *)&iocb->private) |
104 | 110 | #define ocfs2_iocb_rw_locked_level(iocb) \ | |
111 | test_bit(1, (unsigned long *)&iocb->private) | ||
105 | #endif /* OCFS2_FILE_H */ | 112 | #endif /* OCFS2_FILE_H */ |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index e34474c04678..520a2a6d7670 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -1542,7 +1542,7 @@ relock: | |||
1542 | pos = *ppos; | 1542 | pos = *ppos; |
1543 | 1543 | ||
1544 | /* communicate with ocfs2_dio_end_io */ | 1544 | /* communicate with ocfs2_dio_end_io */ |
1545 | ocfs2_iocb_set_rw_locked(iocb); | 1545 | ocfs2_iocb_set_rw_locked(iocb, rw_level); |
1546 | 1546 | ||
1547 | if (direct_io) { | 1547 | if (direct_io) { |
1548 | written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos, | 1548 | written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos, |
@@ -1788,7 +1788,7 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, | |||
1788 | } | 1788 | } |
1789 | rw_level = 0; | 1789 | rw_level = 0; |
1790 | /* communicate with ocfs2_dio_end_io */ | 1790 | /* communicate with ocfs2_dio_end_io */ |
1791 | ocfs2_iocb_set_rw_locked(iocb); | 1791 | ocfs2_iocb_set_rw_locked(iocb, rw_level); |
1792 | } | 1792 | } |
1793 | 1793 | ||
1794 | /* | 1794 | /* |