aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/aops.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index 0bad69ed6336..76251600cbea 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -999,6 +999,7 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
999{ 999{
1000 struct file *file = iocb->ki_filp; 1000 struct file *file = iocb->ki_filp;
1001 struct inode *inode = file->f_mapping->host; 1001 struct inode *inode = file->f_mapping->host;
1002 struct address_space *mapping = inode->i_mapping;
1002 struct gfs2_inode *ip = GFS2_I(inode); 1003 struct gfs2_inode *ip = GFS2_I(inode);
1003 struct gfs2_holder gh; 1004 struct gfs2_holder gh;
1004 int rv; 1005 int rv;
@@ -1019,6 +1020,35 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
1019 if (rv != 1) 1020 if (rv != 1)
1020 goto out; /* dio not valid, fall back to buffered i/o */ 1021 goto out; /* dio not valid, fall back to buffered i/o */
1021 1022
1023 /*
1024 * Now since we are holding a deferred (CW) lock at this point, you
1025 * might be wondering why this is ever needed. There is a case however
1026 * where we've granted a deferred local lock against a cached exclusive
1027 * glock. That is ok provided all granted local locks are deferred, but
1028 * it also means that it is possible to encounter pages which are
1029 * cached and possibly also mapped. So here we check for that and sort
1030 * them out ahead of the dio. The glock state machine will take care of
1031 * everything else.
1032 *
1033 * If in fact the cached glock state (gl->gl_state) is deferred (CW) in
1034 * the first place, mapping->nr_pages will always be zero.
1035 */
1036 if (mapping->nrpages) {
1037 loff_t lstart = offset & (PAGE_CACHE_SIZE - 1);
1038 loff_t len = iov_length(iov, nr_segs);
1039 loff_t end = PAGE_ALIGN(offset + len) - 1;
1040
1041 rv = 0;
1042 if (len == 0)
1043 goto out;
1044 if (test_and_clear_bit(GIF_SW_PAGED, &ip->i_flags))
1045 unmap_shared_mapping_range(ip->i_inode.i_mapping, offset, len);
1046 rv = filemap_write_and_wait_range(mapping, lstart, end);
1047 if (rv)
1048 return rv;
1049 truncate_inode_pages_range(mapping, lstart, end);
1050 }
1051
1022 rv = __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, 1052 rv = __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
1023 offset, nr_segs, gfs2_get_block_direct, 1053 offset, nr_segs, gfs2_get_block_direct,
1024 NULL, NULL, 0); 1054 NULL, NULL, 0);