summaryrefslogtreecommitdiffstats
path: root/fs/ext4/ioctl.c
diff options
context:
space:
mode:
authoryangerkun <yangerkun@huawei.com>2019-02-11 00:35:06 -0500
committerBen Hutchings <ben@decadent.org.uk>2019-07-09 22:03:58 +0100
commit5d4e23ebaed66e2e61d6772a79e462eb3489ebe7 (patch)
tree887f9dbdaef3c923ee8be17210db7f5011b8d1b8 /fs/ext4/ioctl.c
parent4f9fd21c99aca0c26228ba207e95132e9f3cdd24 (diff)
downloadlinux-stable-5d4e23ebaed66e2e61d6772a79e462eb3489ebe7.tar.gz
linux-stable-5d4e23ebaed66e2e61d6772a79e462eb3489ebe7.tar.bz2
linux-stable-5d4e23ebaed66e2e61d6772a79e462eb3489ebe7.zip
ext4: add mask of ext4 flags to swap
commit abdc644e8cbac2e9b19763680e5a7cf9bab2bee7 upstream. The reason is that while swapping two inode, we swap the flags too. Some flags such as EXT4_JOURNAL_DATA_FL can really confuse the things since we're not resetting the address operations structure. The simplest way to keep things sane is to restrict the flags that can be swapped. Signed-off-by: yangerkun <yangerkun@huawei.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu> [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'fs/ext4/ioctl.c')
-rw-r--r--fs/ext4/ioctl.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 88f3b7e3c44e..99bfe22f2a71 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -61,6 +61,7 @@ static void swap_inode_data(struct inode *inode1, struct inode *inode2)
loff_t isize;
struct ext4_inode_info *ei1;
struct ext4_inode_info *ei2;
+ unsigned long tmp;
ei1 = EXT4_I(inode1);
ei2 = EXT4_I(inode2);
@@ -71,7 +72,10 @@ static void swap_inode_data(struct inode *inode1, struct inode *inode2)
memswap(&inode1->i_mtime, &inode2->i_mtime, sizeof(inode1->i_mtime));
memswap(ei1->i_data, ei2->i_data, sizeof(ei1->i_data));
- memswap(&ei1->i_flags, &ei2->i_flags, sizeof(ei1->i_flags));
+ tmp = ei1->i_flags & EXT4_FL_SHOULD_SWAP;
+ ei1->i_flags = (ei2->i_flags & EXT4_FL_SHOULD_SWAP) |
+ (ei1->i_flags & ~EXT4_FL_SHOULD_SWAP);
+ ei2->i_flags = tmp | (ei2->i_flags & ~EXT4_FL_SHOULD_SWAP);
memswap(&ei1->i_disksize, &ei2->i_disksize, sizeof(ei1->i_disksize));
ext4_es_remove_extent(inode1, 0, EXT_MAX_BLOCKS);
ext4_es_remove_extent(inode2, 0, EXT_MAX_BLOCKS);