potential data race on BTRFS_I(inode)->root->last_log_commit when adding inode while fdatasync

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

 



Hi Btrfs Developers,

While fuzzing btrfs I notice a potential data race on
BTRFS_I(inode)->root->last_log_commit and log_transid when an inode is
being added and fdatasync-ed at the same time. Following is the
execution trace:

[Setup]
mkdir("foo", 511) = 0;
open("foo", 65536, 511) = 3;

[Thread 1]
mkdirat(-100, "bar", 246);

__do_sys_mkdirat
  do_mkdirat
    vfs_mkdir
      btrfs_mkdir
        btrfs_new_inode
          btrfs_set_inode_last_trans
            [READ] BTRFS_I(inode)->last_sub_trans =
BTRFS_I(inode)->root->log_transid;

           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            [READ] BTRFS_I(inode)->last_log_commit =
BTRFS_I(inode)->root->last_log_commit;

             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^



[Thread 2]
fdatasync(3);

__do_sys_fdatasync
  do_fsync
    vfs_fsync
      vfs_fsync_range
        btrfs_sync_file
          btrfs_log_dentry_safe
            btrfs_log_inode_parent
              start_log_trans
                btrfs_add_log_tree
                  [WRITE] root->log_transid = 0;
                  [WRITE] root->last_log_commit = 0;


The trace seems fine based on the program order. However, if adding
the memory model into consideration, i.e., the inter-leavings of the
writes and reads, it is possible that the two [READ] receives
inconsistent information about BTRFS_I(inode)->root->*. For example,
BTRFS_I(inode)->root->log_transid is 0 while
BTRFS_I(inode)->root->last_log_commit is a stale value (or the other
way round). This may have a negative impact when persisting the
mkdirat-created inode?

Best Regards,
Meng



[Index of Archives]     [Linux Filesystem Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux