• Louis Rilling's avatar
    configfs: Fix failing mkdir() making racing rmdir() fail · 6d8344ba
    Louis Rilling authored
    When fixing the rename() vs rmdir() deadlock, we stopped locking default groups'
    inodes in configfs_detach_prep(), letting racing mkdir() in default groups
    proceed concurrently. This enables races like below happen, which leads to a
    failing mkdir() making rmdir() fail, despite the group to remove having no
    user-created directory under it in the end.
    
    	process A: 			process B:
    	/* PWD=A/B */
    	mkdir("C")
    	  make_item("C")
    	  attach_group("C")
    					rmdir("A")
    					  detach_prep("A")
    					    detach_prep("B")
    					      error because of "C"
    					  return -ENOTEMPTY
    	    attach_group("C/D")
    	      error (eg -ENOMEM)
    	  return -ENOMEM
    
    This patch prevents such scenarii by making rmdir() wait as long as
    detach_prep() fails because a racing mkdir() is in the middle of attach_group().
    To achieve this, mkdir() sets a flag CONFIGFS_USET_IN_MKDIR in parent's
    configfs_dirent before calling attach_group(), and clears the flag once
    attach_group() is done. detach_prep() fails with -EAGAIN whenever the flag is
    hit and returns the guilty inode's mutex so that rmdir() can wait on it.
    Signed-off-by: default avatarLouis Rilling <Louis.Rilling@kerlabs.com>
    Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
    6d8344ba
configfs_internal.h 4.78 KB