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: David Sterba <dsterba@suse.cz> Reviewed-by: Satoru Takeuchi <takeuchi_satoru@jp.fujitsu.com> Signed-off-by: Filipe David Borba Manana <fdmanana@gmail.com> Signed-off-by: Chris Mason <clm@fb.com>
This commit is contained in:
parent
472b909ff6
commit
3cc7939255
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue