Commit 3cc79392 authored by Filipe Manana's avatar Filipe Manana Committed by Chris Mason

Btrfs: atomically set inode->i_flags in btrfs_update_iflags

This change is based on the corresponding recent change for ext4:

  ext4: atomically set inode->i_flags in ext4_set_inode_flags()

That has the following commit message that applies to btrfs as well:

  "Use cmpxchg() to atomically set i_flags instead of clearing out the
   S_IMMUTABLE, S_APPEND, etc. flags and then setting them from the
   EXT4_IMMUTABLE_FL, EXT4_APPEND_FL flags, since this opens up a race
   where an immutable file has the immutable flag cleared for a brief
   window of time."

Replacing EXT4_IMMUTABLE_FL and EXT4_APPEND_FL with BTRFS_INODE_IMMUTABLE
and BTRFS_INODE_APPEND, respectively.
Reviewed-by: default avatarDavid Sterba <dsterba@suse.cz>
Reviewed-by: default avatarSatoru Takeuchi <takeuchi_satoru@jp.fujitsu.com>
Signed-off-by: default avatarFilipe David Borba Manana <fdmanana@gmail.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent 472b909f
......@@ -136,19 +136,22 @@ static unsigned int btrfs_flags_to_ioctl(unsigned int flags)
void btrfs_update_iflags(struct inode *inode)
{
struct btrfs_inode *ip = BTRFS_I(inode);
inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
unsigned int new_fl = 0;
if (ip->flags & BTRFS_INODE_SYNC)
inode->i_flags |= S_SYNC;
new_fl |= S_SYNC;
if (ip->flags & BTRFS_INODE_IMMUTABLE)
inode->i_flags |= S_IMMUTABLE;
new_fl |= S_IMMUTABLE;
if (ip->flags & BTRFS_INODE_APPEND)
inode->i_flags |= S_APPEND;
new_fl |= S_APPEND;
if (ip->flags & BTRFS_INODE_NOATIME)
inode->i_flags |= S_NOATIME;
new_fl |= S_NOATIME;
if (ip->flags & BTRFS_INODE_DIRSYNC)
inode->i_flags |= S_DIRSYNC;
new_fl |= S_DIRSYNC;
set_mask_bits(&inode->i_flags,
S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | S_DIRSYNC,
new_fl);
}
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment