This is a note to let you know that I've just added the patch titled GFS2: Fix incorrect invalidation for DIO/buffered I/O to the 3.12-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: gfs2-fix-incorrect-invalidation-for-dio-buffered-i-o.patch and it can be found in the queue-3.12 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From dfd11184d894cd0a92397b25cac18831a1a6a5bc Mon Sep 17 00:00:00 2001 From: Steven Whitehouse <swhiteho@xxxxxxxxxx> Date: Wed, 18 Dec 2013 14:14:52 +0000 Subject: GFS2: Fix incorrect invalidation for DIO/buffered I/O From: Steven Whitehouse <swhiteho@xxxxxxxxxx> commit dfd11184d894cd0a92397b25cac18831a1a6a5bc upstream. In patch 209806aba9d540dde3db0a5ce72307f85f33468f we allowed local deferred locks to be granted against a cached exclusive lock. That opened up a corner case which this patch now fixes. The solution to the problem is to check whether we have cached pages each time we do direct I/O and if so to unmap, flush and invalidate those pages. Since the glock state machine normally does that for us, mostly the code will be a no-op. Signed-off-by: Steven Whitehouse <swhiteho@xxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- fs/gfs2/aops.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -984,6 +984,7 @@ static ssize_t gfs2_direct_IO(int rw, st { struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; + struct address_space *mapping = inode->i_mapping; struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_holder gh; int rv; @@ -1004,6 +1005,35 @@ static ssize_t gfs2_direct_IO(int rw, st if (rv != 1) goto out; /* dio not valid, fall back to buffered i/o */ + /* + * Now since we are holding a deferred (CW) lock at this point, you + * might be wondering why this is ever needed. There is a case however + * where we've granted a deferred local lock against a cached exclusive + * glock. That is ok provided all granted local locks are deferred, but + * it also means that it is possible to encounter pages which are + * cached and possibly also mapped. So here we check for that and sort + * them out ahead of the dio. The glock state machine will take care of + * everything else. + * + * If in fact the cached glock state (gl->gl_state) is deferred (CW) in + * the first place, mapping->nr_pages will always be zero. + */ + if (mapping->nrpages) { + loff_t lstart = offset & (PAGE_CACHE_SIZE - 1); + loff_t len = iov_length(iov, nr_segs); + loff_t end = PAGE_ALIGN(offset + len) - 1; + + rv = 0; + if (len == 0) + goto out; + if (test_and_clear_bit(GIF_SW_PAGED, &ip->i_flags)) + unmap_shared_mapping_range(ip->i_inode.i_mapping, offset, len); + rv = filemap_write_and_wait_range(mapping, lstart, end); + if (rv) + return rv; + truncate_inode_pages_range(mapping, lstart, end); + } + rv = __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, offset, nr_segs, gfs2_get_block_direct, NULL, NULL, 0); Patches currently in stable-queue which might be from swhiteho@xxxxxxxxxx are queue-3.12/gfs2-fix-slab-memory-leak-in-gfs2_bufdata.patch queue-3.12/gfs2-fix-incorrect-invalidation-for-dio-buffered-i-o.patch queue-3.12/gfs2-don-t-hold-s_umount-over-blkdev_put.patch queue-3.12/gfs2-fix-use-after-free-race-when-calling-gfs2_remove_from_ail.patch -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html