• Dmitry Monakhov's avatar
    relay: move remove_buf_file inside relay_close_buf · b8d4a5bf
    Dmitry Monakhov authored
    Currently remove_buf_file callback is called from from kobject
    release method. This result in follow issue:
    # blktrace -d /dev/sda1 -d /dev/sda -o test
    
    blktrace_setup()
     dir = create_dir()
     rchan = relay_open(dir,...)
     ->create_buf_file_callback
        buf_file  = debugfs_create_file(dir, )
    
    Userspace will open buf_file.
    Later we make a decision to stop tracing
    blktrace_down()
      relay_close(rhcan)  /* just decrement kobj reference  */
                          /* since it is not zero then callback not called */
      debugfs_remove(dir) /* FAIL due to non empty dir   */
    
    Later user space will close the file and file will be deleted,
    but directory still exist.
    user_space_close()
     ->file_release
       ->release_buf_file_callback
         ->debugfs_remove(buf_file
    ## TESTCASE:
    # blktrace -d /dev/sda1 -d /dev/sda -o test
    # After that blktrace infrastructure will remain broken in
    # an unusable state so: blktrace -d /dev/sda1 will not work.
    
    In fact this is general issue, blktrace is just one of examples.
    We can not reliably remove parent dir until all users close the
    buf_file.
    
    Solution: We don't have to wait that long. File should be deleted inside
    relay_close_buf().
    Signed-off-by: default avatarDmitry Monakhov <dmonakhov@openvz.org>
    Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
    b8d4a5bf
relay.c 32.8 KB