• Louis Rilling's avatar
    [PATCH] configfs: Fix failing symlink() making rmdir() fail · 9a73d78c
    Louis Rilling authored
    On a similar pattern as mkdir() vs rmdir(), a failing symlink() may make rmdir()
    fail for the symlink's parent and the symlink's target as well.
    
    failing symlink() making target's rmdir() fail:
    
    	process 1:				process 2:
    	symlink("A/S" -> "B")
    	  allow_link()
    	  create_link()
    	    attach to "B" links list
    						rmdir("B")
    						  detach_prep("B")
    						    error because of new link
    	    configfs_create_link("A", "S")
    	      error (eg -ENOMEM)
    
    failing symlink() making parent's rmdir() fail:
    
    	process 1:				process 2:
    	symlink("A/D/S" -> "B")
    	  allow_link()
    	  create_link()
    	    attach to "B" links list
    	    configfs_create_link("A/D", "S")
    	      make_dirent("A/D", "S")
    						rmdir("A")
    						  detach_prep("A")
    						    detach_prep("A/D")
    						      error because of "S"
    	      create("S")
    	        error (eg -ENOMEM)
    
    We cannot use the same solution as for mkdir() vs rmdir(), since rmdir() on the
    target cannot wait on the i_mutex of the new symlink's parent without risking a
    deadlock (with other symlink() or sys_rename()). Instead we define a global
    mutex protecting all configfs symlinks attachment, so that rmdir() can avoid the
    races above.
    Signed-off-by: default avatarLouis Rilling <louis.rilling@kerlabs.com>
    Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
    Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
    9a73d78c
symlink.c 7.16 KB