From a253701a7a3934455453591cc2b0a51ef577f99d Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Wed, 1 Jul 2020 21:39:07 -0400 Subject: [PATCH] Fixes for 5.7 Signed-off-by: Sasha Levin --- ...-missing-brelse-calls-on-error-paths.patch | 60 ++++++++++++ ...ync_filesystem-for-read-only-remount.patch | 59 ++++++++++++ .../exfat-flush-dirty-metadata-in-fsync.patch | 95 +++++++++++++++++++ ...ng-vol_dirty-over-exfat_remove_entri.patch | 45 +++++++++ ...used-characters-of-filename-field-to.patch | 45 +++++++++ queue-5.7/series | 5 + 6 files changed, 309 insertions(+) create mode 100644 queue-5.7/exfat-add-missing-brelse-calls-on-error-paths.patch create mode 100644 queue-5.7/exfat-call-sync_filesystem-for-read-only-remount.patch create mode 100644 queue-5.7/exfat-flush-dirty-metadata-in-fsync.patch create mode 100644 queue-5.7/exfat-move-setting-vol_dirty-over-exfat_remove_entri.patch create mode 100644 queue-5.7/exfat-set-the-unused-characters-of-filename-field-to.patch create mode 100644 queue-5.7/series diff --git a/queue-5.7/exfat-add-missing-brelse-calls-on-error-paths.patch b/queue-5.7/exfat-add-missing-brelse-calls-on-error-paths.patch new file mode 100644 index 00000000000..a6e9c59e770 --- /dev/null +++ b/queue-5.7/exfat-add-missing-brelse-calls-on-error-paths.patch @@ -0,0 +1,60 @@ +From 90c584bc648beeaa8db960a3a8ad99e5320621aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Jun 2020 20:22:13 +0300 +Subject: exfat: add missing brelse() calls on error paths + +From: Dan Carpenter + +[ Upstream commit e8dd3cda8667118b70d9fe527f61fe22623de04d ] + +If the second exfat_get_dentry() call fails then we need to release +"old_bh" before returning. There is a similar bug in exfat_move_file(). + +Fixes: 5f2aa075070c ("exfat: add inode operations") +Reported-by: Markus Elfring +Signed-off-by: Dan Carpenter +Signed-off-by: Namjae Jeon +Signed-off-by: Sasha Levin +--- + fs/exfat/namei.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c +index a2659a8a68a14..3bf1dbadab691 100644 +--- a/fs/exfat/namei.c ++++ b/fs/exfat/namei.c +@@ -1089,10 +1089,14 @@ static int exfat_rename_file(struct inode *inode, struct exfat_chain *p_dir, + + epold = exfat_get_dentry(sb, p_dir, oldentry + 1, &old_bh, + §or_old); ++ if (!epold) ++ return -EIO; + epnew = exfat_get_dentry(sb, p_dir, newentry + 1, &new_bh, + §or_new); +- if (!epold || !epnew) ++ if (!epnew) { ++ brelse(old_bh); + return -EIO; ++ } + + memcpy(epnew, epold, DENTRY_SIZE); + exfat_update_bh(sb, new_bh, sync); +@@ -1173,10 +1177,14 @@ static int exfat_move_file(struct inode *inode, struct exfat_chain *p_olddir, + + epmov = exfat_get_dentry(sb, p_olddir, oldentry + 1, &mov_bh, + §or_mov); ++ if (!epmov) ++ return -EIO; + epnew = exfat_get_dentry(sb, p_newdir, newentry + 1, &new_bh, + §or_new); +- if (!epmov || !epnew) ++ if (!epnew) { ++ brelse(mov_bh); + return -EIO; ++ } + + memcpy(epnew, epmov, DENTRY_SIZE); + exfat_update_bh(sb, new_bh, IS_DIRSYNC(inode)); +-- +2.25.1 + diff --git a/queue-5.7/exfat-call-sync_filesystem-for-read-only-remount.patch b/queue-5.7/exfat-call-sync_filesystem-for-read-only-remount.patch new file mode 100644 index 00000000000..8482989be28 --- /dev/null +++ b/queue-5.7/exfat-call-sync_filesystem-for-read-only-remount.patch @@ -0,0 +1,59 @@ +From ebfe8d51296159d54f4559162955b58e40621108 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Jun 2020 14:34:45 +0900 +Subject: exfat: call sync_filesystem for read-only remount + +From: Hyunchul Lee + +[ Upstream commit a0271a15cf2cf907ea5b0f2ba611123f1b7935ec ] + +We need to commit dirty metadata and pages to disk +before remounting exfat as read-only. + +This fixes a failure in xfstests generic/452 + +generic/452 does the following: +cp something / +mount -o remount,ro + +the /something is corrupted. because while +exfat is remounted as read-only, exfat doesn't +have a chance to commit metadata and +vfs invalidates page caches in a block device. + +Signed-off-by: Hyunchul Lee +Acked-by: Sungjong Seo +Signed-off-by: Namjae Jeon +Signed-off-by: Sasha Levin +--- + fs/exfat/super.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/fs/exfat/super.c b/fs/exfat/super.c +index c1b1ed306a485..e879801533980 100644 +--- a/fs/exfat/super.c ++++ b/fs/exfat/super.c +@@ -637,10 +637,20 @@ static void exfat_free(struct fs_context *fc) + } + } + ++static int exfat_reconfigure(struct fs_context *fc) ++{ ++ fc->sb_flags |= SB_NODIRATIME; ++ ++ /* volume flag will be updated in exfat_sync_fs */ ++ sync_filesystem(fc->root->d_sb); ++ return 0; ++} ++ + static const struct fs_context_operations exfat_context_ops = { + .parse_param = exfat_parse_param, + .get_tree = exfat_get_tree, + .free = exfat_free, ++ .reconfigure = exfat_reconfigure, + }; + + static int exfat_init_fs_context(struct fs_context *fc) +-- +2.25.1 + diff --git a/queue-5.7/exfat-flush-dirty-metadata-in-fsync.patch b/queue-5.7/exfat-flush-dirty-metadata-in-fsync.patch new file mode 100644 index 00000000000..fe768ebae2d --- /dev/null +++ b/queue-5.7/exfat-flush-dirty-metadata-in-fsync.patch @@ -0,0 +1,95 @@ +From 79772ff5f4347cef5f837768fa934516ed2a4824 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Jun 2020 20:43:26 +0900 +Subject: exfat: flush dirty metadata in fsync + +From: Sungjong Seo + +[ Upstream commit 5267456e953fd8c5abd8e278b1cc6a9f9027ac0a ] + +generic_file_fsync() exfat used could not guarantee the consistency of +a file because it has flushed not dirty metadata but only dirty data pages +for a file. + +Instead of that, use exfat_file_fsync() for files and directories so that +it guarantees to commit both the metadata and data pages for a file. + +Signed-off-by: Sungjong Seo +Signed-off-by: Namjae Jeon +Signed-off-by: Sasha Levin +--- + fs/exfat/dir.c | 2 +- + fs/exfat/exfat_fs.h | 1 + + fs/exfat/file.c | 19 ++++++++++++++++++- + 3 files changed, 20 insertions(+), 2 deletions(-) + +diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c +index 349ca0c282c2c..6db302d76d4c1 100644 +--- a/fs/exfat/dir.c ++++ b/fs/exfat/dir.c +@@ -314,7 +314,7 @@ const struct file_operations exfat_dir_operations = { + .llseek = generic_file_llseek, + .read = generic_read_dir, + .iterate = exfat_iterate, +- .fsync = generic_file_fsync, ++ .fsync = exfat_file_fsync, + }; + + int exfat_alloc_new_dir(struct inode *inode, struct exfat_chain *clu) +diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h +index d67fb8a6f770c..d865050fa6cd7 100644 +--- a/fs/exfat/exfat_fs.h ++++ b/fs/exfat/exfat_fs.h +@@ -424,6 +424,7 @@ void exfat_truncate(struct inode *inode, loff_t size); + int exfat_setattr(struct dentry *dentry, struct iattr *attr); + int exfat_getattr(const struct path *path, struct kstat *stat, + unsigned int request_mask, unsigned int query_flags); ++int exfat_file_fsync(struct file *file, loff_t start, loff_t end, int datasync); + + /* namei.c */ + extern const struct dentry_operations exfat_dentry_ops; +diff --git a/fs/exfat/file.c b/fs/exfat/file.c +index 5b4ddff187312..b93aa9e6cb16c 100644 +--- a/fs/exfat/file.c ++++ b/fs/exfat/file.c +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + #include "exfat_raw.h" + #include "exfat_fs.h" +@@ -347,12 +348,28 @@ int exfat_setattr(struct dentry *dentry, struct iattr *attr) + return error; + } + ++int exfat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync) ++{ ++ struct inode *inode = filp->f_mapping->host; ++ int err; ++ ++ err = __generic_file_fsync(filp, start, end, datasync); ++ if (err) ++ return err; ++ ++ err = sync_blockdev(inode->i_sb->s_bdev); ++ if (err) ++ return err; ++ ++ return blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); ++} ++ + const struct file_operations exfat_file_operations = { + .llseek = generic_file_llseek, + .read_iter = generic_file_read_iter, + .write_iter = generic_file_write_iter, + .mmap = generic_file_mmap, +- .fsync = generic_file_fsync, ++ .fsync = exfat_file_fsync, + .splice_read = generic_file_splice_read, + .splice_write = iter_file_splice_write, + }; +-- +2.25.1 + diff --git a/queue-5.7/exfat-move-setting-vol_dirty-over-exfat_remove_entri.patch b/queue-5.7/exfat-move-setting-vol_dirty-over-exfat_remove_entri.patch new file mode 100644 index 00000000000..e66efd185ef --- /dev/null +++ b/queue-5.7/exfat-move-setting-vol_dirty-over-exfat_remove_entri.patch @@ -0,0 +1,45 @@ +From 21ef00112c6abaa31d24e572b97f049f0c50e356 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 Jun 2020 12:17:18 +0900 +Subject: exfat: move setting VOL_DIRTY over exfat_remove_entries() + +From: Namjae Jeon + +[ Upstream commit 3bcfb701099acf96b0e883bf5544f96af473aa1d ] + +Move setting VOL_DIRTY over exfat_remove_entries() to avoid unneeded +leaving VOL_DIRTY on -ENOTEMPTY. + +Fixes: 5f2aa075070c ("exfat: add inode operations") +Cc: stable@vger.kernel.org # v5.7 +Reported-by: Tetsuhiro Kohada +Reviewed-by: Sungjong Seo +Signed-off-by: Namjae Jeon +Signed-off-by: Sasha Levin +--- + fs/exfat/namei.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c +index 3bf1dbadab691..2c9c783177213 100644 +--- a/fs/exfat/namei.c ++++ b/fs/exfat/namei.c +@@ -984,7 +984,6 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry) + goto unlock; + } + +- exfat_set_vol_flags(sb, VOL_DIRTY); + exfat_chain_set(&clu_to_free, ei->start_clu, + EXFAT_B_TO_CLU_ROUND_UP(i_size_read(inode), sbi), ei->flags); + +@@ -1012,6 +1011,7 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry) + num_entries++; + brelse(bh); + ++ exfat_set_vol_flags(sb, VOL_DIRTY); + err = exfat_remove_entries(dir, &cdir, entry, 0, num_entries); + if (err) { + exfat_msg(sb, KERN_ERR, +-- +2.25.1 + diff --git a/queue-5.7/exfat-set-the-unused-characters-of-filename-field-to.patch b/queue-5.7/exfat-set-the-unused-characters-of-filename-field-to.patch new file mode 100644 index 00000000000..9fb2caac998 --- /dev/null +++ b/queue-5.7/exfat-set-the-unused-characters-of-filename-field-to.patch @@ -0,0 +1,45 @@ +From 39dd3a7dcf8ec9aa2d4759196c3585150bc0c145 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 9 Jun 2020 14:30:44 +0900 +Subject: exfat: Set the unused characters of FileName field to the value 0000h + +From: Hyeongseok.Kim + +[ Upstream commit 4ba6ccd695f5ed3ae851e59b443b757bbe4557fe ] + +Some fsck tool complain that padding part of the FileName field +is not set to the value 0000h. So let's maintain filesystem cleaner, +as exfat's spec. recommendation. + +Signed-off-by: Hyeongseok.Kim +Reviewed-by: Sungjong Seo +Signed-off-by: Namjae Jeon +Signed-off-by: Sasha Levin +--- + fs/exfat/dir.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c +index 4b91afb0f0515..349ca0c282c2c 100644 +--- a/fs/exfat/dir.c ++++ b/fs/exfat/dir.c +@@ -430,10 +430,12 @@ static void exfat_init_name_entry(struct exfat_dentry *ep, + ep->dentry.name.flags = 0x0; + + for (i = 0; i < EXFAT_FILE_NAME_LEN; i++) { +- ep->dentry.name.unicode_0_14[i] = cpu_to_le16(*uniname); +- if (*uniname == 0x0) +- break; +- uniname++; ++ if (*uniname != 0x0) { ++ ep->dentry.name.unicode_0_14[i] = cpu_to_le16(*uniname); ++ uniname++; ++ } else { ++ ep->dentry.name.unicode_0_14[i] = 0x0; ++ } + } + } + +-- +2.25.1 + diff --git a/queue-5.7/series b/queue-5.7/series new file mode 100644 index 00000000000..3ca96c45ba2 --- /dev/null +++ b/queue-5.7/series @@ -0,0 +1,5 @@ +exfat-set-the-unused-characters-of-filename-field-to.patch +exfat-add-missing-brelse-calls-on-error-paths.patch +exfat-call-sync_filesystem-for-read-only-remount.patch +exfat-move-setting-vol_dirty-over-exfat_remove_entri.patch +exfat-flush-dirty-metadata-in-fsync.patch -- 2.47.3