From 59d9fa5c2e9086db11aa287bb4030151d0095a17 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Thu, 8 Aug 2013 23:01:24 -0400 Subject: ext4: allow the mount options nodelalloc and data=journal Commit 26092bf ("ext4: use a table-driven handler for mount options") wrongly disallows the specifying the mount options nodelalloc and data=journal simultaneously. This is incorrect; it should have only disallowed the combination of delalloc and data=journal simultaneously. Reported-by: Piotr Sarna Signed-off-by: "Theodore Ts'o" Cc: stable@vger.kernel.org diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 36b141e..75b3708 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1359,7 +1359,7 @@ static const struct mount_opts { {Opt_delalloc, EXT4_MOUNT_DELALLOC, MOPT_EXT4_ONLY | MOPT_SET | MOPT_EXPLICIT}, {Opt_nodelalloc, EXT4_MOUNT_DELALLOC, - MOPT_EXT4_ONLY | MOPT_CLEAR | MOPT_EXPLICIT}, + MOPT_EXT4_ONLY | MOPT_CLEAR}, {Opt_journal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM, MOPT_EXT4_ONLY | MOPT_SET}, {Opt_journal_async_commit, (EXT4_MOUNT_JOURNAL_ASYNC_COMMIT | -- cgit v0.10.2 From 6ae6514b33f941d3386da0dfbe2942766eab1577 Mon Sep 17 00:00:00 2001 From: Piotr Sarna Date: Thu, 8 Aug 2013 23:02:24 -0400 Subject: ext4: fix mount/remount error messages for incompatible mount options Commit 5688978 ("ext4: improve handling of conflicting mount options") introduced incorrect messages shown while choosing wrong mount options. First of all, both cases of incorrect mount options, "data=journal,delalloc" and "data=journal,dioread_nolock" result in the same error message. Secondly, the problem above isn't solved for remount option: the mismatched parameter is simply ignored. Moreover, ext4_msg states that remount with options "data=journal,delalloc" succeeded, which is not true. To fix it up, I added a simple check after parse_options() call to ensure that data=journal and delalloc/dioread_nolock parameters are not present at the same time. Signed-off-by: Piotr Sarna Acked-by: Bartlomiej Zolnierkiewicz Signed-off-by: Kyungmin Park Signed-off-by: "Theodore Ts'o" Cc: stable@vger.kernel.org diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 75b3708..b59373b 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3483,7 +3483,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) } if (test_opt(sb, DIOREAD_NOLOCK)) { ext4_msg(sb, KERN_ERR, "can't mount with " - "both data=journal and delalloc"); + "both data=journal and dioread_nolock"); goto failed_mount; } if (test_opt(sb, DELALLOC)) @@ -4727,6 +4727,21 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) goto restore_opts; } + if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { + if (test_opt2(sb, EXPLICIT_DELALLOC)) { + ext4_msg(sb, KERN_ERR, "can't mount with " + "both data=journal and delalloc"); + err = -EINVAL; + goto restore_opts; + } + if (test_opt(sb, DIOREAD_NOLOCK)) { + ext4_msg(sb, KERN_ERR, "can't mount with " + "both data=journal and dioread_nolock"); + err = -EINVAL; + goto restore_opts; + } + } + if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) ext4_abort(sb, "Abort forced by user"); -- cgit v0.10.2 From cde2d7a796f7e895e25b43471ed658079345636d Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 12 Aug 2013 09:29:30 -0400 Subject: ext4: flush the extent status cache during EXT4_IOC_SWAP_BOOT Previously we weren't swapping only some of the extent_status LRU fields during the processing of the EXT4_IOC_SWAP_BOOT ioctl. The much safer thing to do is to just completely flush the extent status tree when doing the swap. Signed-off-by: "Theodore Ts'o" Cc: Zheng Liu Cc: stable@vger.kernel.org diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 9491ac0..c0427e2 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -77,8 +77,10 @@ static void swap_inode_data(struct inode *inode1, struct inode *inode2) memswap(ei1->i_data, ei2->i_data, sizeof(ei1->i_data)); memswap(&ei1->i_flags, &ei2->i_flags, sizeof(ei1->i_flags)); memswap(&ei1->i_disksize, &ei2->i_disksize, sizeof(ei1->i_disksize)); - memswap(&ei1->i_es_tree, &ei2->i_es_tree, sizeof(ei1->i_es_tree)); - memswap(&ei1->i_es_lru_nr, &ei2->i_es_lru_nr, sizeof(ei1->i_es_lru_nr)); + ext4_es_remove_extent(inode1, 0, EXT_MAX_BLOCKS); + ext4_es_remove_extent(inode2, 0, EXT_MAX_BLOCKS); + ext4_es_lru_del(inode1); + ext4_es_lru_del(inode2); isize = i_size_read(inode1); i_size_write(inode1, i_size_read(inode2)); -- cgit v0.10.2