aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glops.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2013-12-19 06:04:14 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2013-12-20 05:42:08 -0500
commit582d2f7aedfde9e1a01170deb003df510aa778d3 (patch)
treeb664990ee66d1e3ca792848e71b05c670379b4ed /fs/gfs2/glops.c
parentdfd11184d894cd0a92397b25cac18831a1a6a5bc (diff)
GFS2: Wait for async DIO in glock state changes
We need to wait for any outstanding DIO to complete in a couple of situations. Firstly, in case we are changing out of deferred mode (in inode_go_sync) where GLF_DIRTY will not be set. That call could be prefixed with a test for gl_state == LM_ST_DEFERRED but it doesn't seem worth it bearing in mind that the test for outstanding DIO is very quick anyway, in the usual case that there is none. The second case is in inode_go_lock which will catch the cases where we have a cached EX lock, but where we grant deferred locks against it so that there is no glock state transistion. We only need to wait if the state is not deferred, since DIO is valid anyway in that state. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/glops.c')
-rw-r--r--fs/gfs2/glops.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index db908f697139..f88dcd925010 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -192,8 +192,11 @@ static void inode_go_sync(struct gfs2_glock *gl)
192 192
193 if (ip && !S_ISREG(ip->i_inode.i_mode)) 193 if (ip && !S_ISREG(ip->i_inode.i_mode))
194 ip = NULL; 194 ip = NULL;
195 if (ip && test_and_clear_bit(GIF_SW_PAGED, &ip->i_flags)) 195 if (ip) {
196 unmap_shared_mapping_range(ip->i_inode.i_mapping, 0, 0); 196 if (test_and_clear_bit(GIF_SW_PAGED, &ip->i_flags))
197 unmap_shared_mapping_range(ip->i_inode.i_mapping, 0, 0);
198 inode_dio_wait(&ip->i_inode);
199 }
197 if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) 200 if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags))
198 return; 201 return;
199 202
@@ -410,6 +413,9 @@ static int inode_go_lock(struct gfs2_holder *gh)
410 return error; 413 return error;
411 } 414 }
412 415
416 if (gh->gh_state != LM_ST_DEFERRED)
417 inode_dio_wait(&ip->i_inode);
418
413 if ((ip->i_diskflags & GFS2_DIF_TRUNC_IN_PROG) && 419 if ((ip->i_diskflags & GFS2_DIF_TRUNC_IN_PROG) &&
414 (gl->gl_state == LM_ST_EXCLUSIVE) && 420 (gl->gl_state == LM_ST_EXCLUSIVE) &&
415 (gh->gh_state == LM_ST_EXCLUSIVE)) { 421 (gh->gh_state == LM_ST_EXCLUSIVE)) {