diff options
author | Tristan Ye <tristan.ye@oracle.com> | 2010-12-07 01:35:07 -0500 |
---|---|---|
committer | Joel Becker <joel.becker@oracle.com> | 2010-12-09 18:36:48 -0500 |
commit | 39c99f12f15c8bf8257985d9b2a2548a03d18c00 (patch) | |
tree | 38f09ce41f6cbfd3a73b1dc66098ba3bf05e2d6a /fs/ocfs2/aops.h | |
parent | 388c4bcb4e63e88fb1f312a2f5f9eb2623afcf5b (diff) |
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>
Diffstat (limited to 'fs/ocfs2/aops.h')
-rw-r--r-- | fs/ocfs2/aops.h | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h index 76bfdfda691a..eceb456037c1 100644 --- a/fs/ocfs2/aops.h +++ b/fs/ocfs2/aops.h | |||
@@ -68,8 +68,27 @@ static inline void ocfs2_iocb_set_rw_locked(struct kiocb *iocb, int level) | |||
68 | else | 68 | else |
69 | clear_bit(1, (unsigned long *)&iocb->private); | 69 | clear_bit(1, (unsigned long *)&iocb->private); |
70 | } | 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 | |||
71 | #define ocfs2_iocb_clear_rw_locked(iocb) \ | 84 | #define ocfs2_iocb_clear_rw_locked(iocb) \ |
72 | clear_bit(0, (unsigned long *)&iocb->private) | 85 | clear_bit(OCFS2_IOCB_RW_LOCK, (unsigned long *)&iocb->private) |
73 | #define ocfs2_iocb_rw_locked_level(iocb) \ | 86 | #define ocfs2_iocb_rw_locked_level(iocb) \ |
74 | test_bit(1, (unsigned long *)&iocb->private) | 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) | ||
75 | #endif /* OCFS2_FILE_H */ | 94 | #endif /* OCFS2_FILE_H */ |