Patch "gfs2: Cancel remote delete work asynchronously" has been added to the 5.14-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    gfs2: Cancel remote delete work asynchronously

to the 5.14-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-cancel-remote-delete-work-asynchronously.patch
and it can be found in the queue-5.14 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit c5d52877bbd55586a8a5e379ca7eb37b7d7d94ce
Author: Andreas Gruenbacher <agruenba@xxxxxxxxxx>
Date:   Mon Oct 11 20:53:02 2021 +0200

    gfs2: Cancel remote delete work asynchronously
    
    [ Upstream commit 486408d690e130c3adacf816754b97558d715f46 ]
    
    In gfs2_inode_lookup and gfs2_create_inode, we're calling
    gfs2_cancel_delete_work which currently cancels any remote delete work
    (delete_work_func) synchronously.  This means that if the work is
    currently running, it will wait for it to finish.  We're doing this to
    pevent a previous instance of an inode from having any influence on the
    next instance.
    
    However, delete_work_func uses gfs2_inode_lookup internally, and we can
    end up in a deadlock when delete_work_func gets interrupted at the wrong
    time.  For example,
    
      (1) An inode's iopen glock has delete work queued, but the inode
          itself has been evicted from the inode cache.
    
      (2) The delete work is preempted before reaching gfs2_inode_lookup.
    
      (3) Another process recreates the inode (gfs2_create_inode).  It tries
          to cancel any outstanding delete work, which blocks waiting for
          the ongoing delete work to finish.
    
      (4) The delete work calls gfs2_inode_lookup, which blocks waiting for
          gfs2_create_inode to instantiate and unlock the new inode =>
          deadlock.
    
    It turns out that when the delete work notices that its inode has been
    re-instantiated, it will do nothing.  This means that it's safe to
    cancel the delete work asynchronously.  This prevents the kind of
    deadlock described above.
    
    Signed-off-by: Andreas Gruenbacher <agruenba@xxxxxxxxxx>
    Signed-off-by: Bob Peterson <rpeterso@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 1f3902ecddedd..fea68ed127b89 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -1920,7 +1920,7 @@ bool gfs2_queue_delete_work(struct gfs2_glock *gl, unsigned long delay)
 
 void gfs2_cancel_delete_work(struct gfs2_glock *gl)
 {
-	if (cancel_delayed_work_sync(&gl->gl_delete)) {
+	if (cancel_delayed_work(&gl->gl_delete)) {
 		clear_bit(GLF_PENDING_DELETE, &gl->gl_flags);
 		gfs2_glock_put(gl);
 	}



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux