diff options
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/file.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 20fffeed630b..a9559c874530 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -1168,6 +1168,22 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, | |||
1168 | ocfs2_iocb_set_rw_locked(iocb); | 1168 | ocfs2_iocb_set_rw_locked(iocb); |
1169 | } | 1169 | } |
1170 | 1170 | ||
1171 | /* | ||
1172 | * We're fine letting folks race truncates and extending | ||
1173 | * writes with read across the cluster, just like they can | ||
1174 | * locally. Hence no rw_lock during read. | ||
1175 | * | ||
1176 | * Take and drop the meta data lock to update inode fields | ||
1177 | * like i_size. This allows the checks down below | ||
1178 | * generic_file_aio_read() a chance of actually working. | ||
1179 | */ | ||
1180 | ret = ocfs2_meta_lock(inode, NULL, NULL, 0); | ||
1181 | if (ret < 0) { | ||
1182 | mlog_errno(ret); | ||
1183 | goto bail; | ||
1184 | } | ||
1185 | ocfs2_meta_unlock(inode, 0); | ||
1186 | |||
1171 | ret = generic_file_aio_read(iocb, buf, count, iocb->ki_pos); | 1187 | ret = generic_file_aio_read(iocb, buf, count, iocb->ki_pos); |
1172 | if (ret == -EINVAL) | 1188 | if (ret == -EINVAL) |
1173 | mlog(ML_ERROR, "generic_file_aio_read returned -EINVAL\n"); | 1189 | mlog(ML_ERROR, "generic_file_aio_read returned -EINVAL\n"); |