aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Peterson <rpeterso@redhat.com>2015-12-07 17:24:27 -0500
committerBob Peterson <rpeterso@redhat.com>2016-03-15 10:46:37 -0400
commita4923865ea071b0bd708339df7a83c76732fa2db (patch)
tree26f80b7fe5be0b047ce37fe198d0a4ec797fccdd
parent2df6f47150b6afbb258ed1d5c9ed78c23df05053 (diff)
GFS2: Prevent delete work from occurring on glocks used for create
This patch tries to prevent delete work (queued via iopen callback) from executing if the glock is currently being used to create a new inode. Signed-off-by: Bob Peterson <rpeterso@redhat.com> Acked-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/gfs2/glock.c7
-rw-r--r--fs/gfs2/incore.h1
-rw-r--r--fs/gfs2/inode.c7
3 files changed, 14 insertions, 1 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 5788ebff716a..7f0257309b3e 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -572,6 +572,12 @@ static void delete_work_func(struct work_struct *work)
572 struct inode *inode; 572 struct inode *inode;
573 u64 no_addr = gl->gl_name.ln_number; 573 u64 no_addr = gl->gl_name.ln_number;
574 574
575 /* If someone's using this glock to create a new dinode, the block must
576 have been freed by another node, then re-used, in which case our
577 iopen callback is too late after the fact. Ignore it. */
578 if (test_bit(GLF_INODE_CREATING, &gl->gl_flags))
579 goto out;
580
575 ip = gl->gl_object; 581 ip = gl->gl_object;
576 /* Note: Unsafe to dereference ip as we don't hold right refs/locks */ 582 /* Note: Unsafe to dereference ip as we don't hold right refs/locks */
577 583
@@ -583,6 +589,7 @@ static void delete_work_func(struct work_struct *work)
583 d_prune_aliases(inode); 589 d_prune_aliases(inode);
584 iput(inode); 590 iput(inode);
585 } 591 }
592out:
586 gfs2_glock_put(gl); 593 gfs2_glock_put(gl);
587} 594}
588 595
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 845fb09cc606..a6a3389a07fc 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -328,6 +328,7 @@ enum {
328 GLF_LRU = 13, 328 GLF_LRU = 13,
329 GLF_OBJECT = 14, /* Used only for tracing */ 329 GLF_OBJECT = 14, /* Used only for tracing */
330 GLF_BLOCKING = 15, 330 GLF_BLOCKING = 15,
331 GLF_INODE_CREATING = 16, /* Inode creation occurring */
331}; 332};
332 333
333struct gfs2_glock { 334struct gfs2_glock {
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 3e94400d587c..95a914524a39 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -592,7 +592,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
592 struct inode *inode = NULL; 592 struct inode *inode = NULL;
593 struct gfs2_inode *dip = GFS2_I(dir), *ip; 593 struct gfs2_inode *dip = GFS2_I(dir), *ip;
594 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); 594 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
595 struct gfs2_glock *io_gl; 595 struct gfs2_glock *io_gl = NULL;
596 int error, free_vfs_inode = 1; 596 int error, free_vfs_inode = 1;
597 u32 aflags = 0; 597 u32 aflags = 0;
598 unsigned blocks = 1; 598 unsigned blocks = 1;
@@ -729,6 +729,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
729 if (error) 729 if (error)
730 goto fail_gunlock2; 730 goto fail_gunlock2;
731 731
732 BUG_ON(test_and_set_bit(GLF_INODE_CREATING, &io_gl->gl_flags));
733
732 error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); 734 error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
733 if (error) 735 if (error)
734 goto fail_gunlock2; 736 goto fail_gunlock2;
@@ -771,12 +773,15 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
771 } 773 }
772 gfs2_glock_dq_uninit(ghs); 774 gfs2_glock_dq_uninit(ghs);
773 gfs2_glock_dq_uninit(ghs + 1); 775 gfs2_glock_dq_uninit(ghs + 1);
776 clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags);
774 return error; 777 return error;
775 778
776fail_gunlock3: 779fail_gunlock3:
777 gfs2_glock_dq_uninit(&ip->i_iopen_gh); 780 gfs2_glock_dq_uninit(&ip->i_iopen_gh);
778 gfs2_glock_put(io_gl); 781 gfs2_glock_put(io_gl);
779fail_gunlock2: 782fail_gunlock2:
783 if (io_gl)
784 clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags);
780 gfs2_glock_dq_uninit(ghs + 1); 785 gfs2_glock_dq_uninit(ghs + 1);
781fail_free_inode: 786fail_free_inode:
782 if (ip->i_gl) 787 if (ip->i_gl)