aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhang Zhen <zhenzhang.zhang@huawei.com>2014-04-15 02:19:38 -0400
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2014-05-06 21:21:54 -0400
commit8abfb36ab396377ea712cd640c525fd5535d1dc9 (patch)
tree89e5bd1f683cc4428b95a66aa01303417249c8f8
parentb156d542415d88c265a0a579448a93e66aa18e33 (diff)
f2fs: atomically set inode->i_flags in f2fs_set_inode_flags()
Use set_mask_bits() to atomically set i_flags instead of clearing out the S_IMMUTABLE, S_APPEND, etc. flags and then setting them from the FS_IMMUTABLE_FL, FS_APPEND_FL, etc. flags, since this opens up a race where an immutable file has the immutable flag cleared for a brief window of time. Signed-off-by: Zhang Zhen <zhenzhang.zhang@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
-rw-r--r--fs/f2fs/inode.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index ee829d360468..f7a655373c46 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -12,6 +12,7 @@
12#include <linux/f2fs_fs.h> 12#include <linux/f2fs_fs.h>
13#include <linux/buffer_head.h> 13#include <linux/buffer_head.h>
14#include <linux/writeback.h> 14#include <linux/writeback.h>
15#include <linux/bitops.h>
15 16
16#include "f2fs.h" 17#include "f2fs.h"
17#include "node.h" 18#include "node.h"
@@ -21,20 +22,20 @@
21void f2fs_set_inode_flags(struct inode *inode) 22void f2fs_set_inode_flags(struct inode *inode)
22{ 23{
23 unsigned int flags = F2FS_I(inode)->i_flags; 24 unsigned int flags = F2FS_I(inode)->i_flags;
24 25 unsigned int new_fl = 0;
25 inode->i_flags &= ~(S_SYNC | S_APPEND | S_IMMUTABLE |
26 S_NOATIME | S_DIRSYNC);
27 26
28 if (flags & FS_SYNC_FL) 27 if (flags & FS_SYNC_FL)
29 inode->i_flags |= S_SYNC; 28 new_fl |= S_SYNC;
30 if (flags & FS_APPEND_FL) 29 if (flags & FS_APPEND_FL)
31 inode->i_flags |= S_APPEND; 30 new_fl |= S_APPEND;
32 if (flags & FS_IMMUTABLE_FL) 31 if (flags & FS_IMMUTABLE_FL)
33 inode->i_flags |= S_IMMUTABLE; 32 new_fl |= S_IMMUTABLE;
34 if (flags & FS_NOATIME_FL) 33 if (flags & FS_NOATIME_FL)
35 inode->i_flags |= S_NOATIME; 34 new_fl |= S_NOATIME;
36 if (flags & FS_DIRSYNC_FL) 35 if (flags & FS_DIRSYNC_FL)
37 inode->i_flags |= S_DIRSYNC; 36 new_fl |= S_DIRSYNC;
37 set_mask_bits(&inode->i_flags,
38 S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC, new_fl);
38} 39}
39 40
40static void __get_inode_rdev(struct inode *inode, struct f2fs_inode *ri) 41static void __get_inode_rdev(struct inode *inode, struct f2fs_inode *ri)