Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+14 -1
+7
fs/gfs2/glock.c
··· 572 572 struct inode *inode; 573 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 581 ip = gl->gl_object; 576 582 /* Note: Unsafe to dereference ip as we don't hold right refs/locks */ 577 583 ··· 589 583 d_prune_aliases(inode); 590 584 iput(inode); 591 585 } 586 + out: 592 587 gfs2_glock_put(gl); 593 588 } 594 589
+1
fs/gfs2/incore.h
··· 328 328 GLF_LRU = 13, 329 329 GLF_OBJECT = 14, /* Used only for tracing */ 330 330 GLF_BLOCKING = 15, 331 + GLF_INODE_CREATING = 16, /* Inode creation occurring */ 331 332 }; 332 333 333 334 struct gfs2_glock {
+6 -1
fs/gfs2/inode.c
··· 592 592 struct inode *inode = NULL; 593 593 struct gfs2_inode *dip = GFS2_I(dir), *ip; 594 594 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); 595 - struct gfs2_glock *io_gl; 595 + struct gfs2_glock *io_gl = NULL; 596 596 int error, free_vfs_inode = 1; 597 597 u32 aflags = 0; 598 598 unsigned blocks = 1; ··· 729 729 if (error) 730 730 goto fail_gunlock2; 731 731 732 + BUG_ON(test_and_set_bit(GLF_INODE_CREATING, &io_gl->gl_flags)); 733 + 732 734 error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); 733 735 if (error) 734 736 goto fail_gunlock2; ··· 773 771 } 774 772 gfs2_glock_dq_uninit(ghs); 775 773 gfs2_glock_dq_uninit(ghs + 1); 774 + clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags); 776 775 return error; 777 776 778 777 fail_gunlock3: 779 778 gfs2_glock_dq_uninit(&ip->i_iopen_gh); 780 779 gfs2_glock_put(io_gl); 781 780 fail_gunlock2: 781 + if (io_gl) 782 + clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags); 782 783 gfs2_glock_dq_uninit(ghs + 1); 783 784 fail_free_inode: 784 785 if (ip->i_gl)