Could you please push exfat stable patches into 5.7.y kernel tree ?
Thanks!
Dan Carpenter (1): exfat: add missing brelse() calls on error paths
Hyeongseok.Kim (1): exfat: Set the unused characters of FileName field to the value 0000h
Hyunchul Lee (1): exfat: call sync_filesystem for read-only remount
Namjae Jeon (1): exfat: move setting VOL_DIRTY over exfat_remove_entries()
Sungjong Seo (1): exfat: flush dirty metadata in fsync
fs/exfat/dir.c | 12 +++++++----- fs/exfat/exfat_fs.h | 1 + fs/exfat/file.c | 19 ++++++++++++++++++- fs/exfat/namei.c | 14 +++++++++++--- fs/exfat/super.c | 10 ++++++++++ 5 files changed, 47 insertions(+), 9 deletions(-)
From: "Hyeongseok.Kim" Hyeongseok@gmail.com
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.
Fixes: ca06197382bd ("exfat: add directory operations") Cc: stable@vger.kernel.org # v5.7 Signed-off-by: Hyeongseok.Kim Hyeongseok@gmail.com Reviewed-by: Sungjong Seo sj1557.seo@samsung.com Signed-off-by: Namjae Jeon namjae.jeon@samsung.com --- 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 4b91afb0f051..349ca0c282c2 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; + } } }
From: Dan Carpenter dan.carpenter@oracle.com
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") Cc: stable@vger.kernel.org # v5.7 Reported-by: Markus Elfring Markus.Elfring@web.de Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Namjae Jeon namjae.jeon@samsung.com --- 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 a2659a8a68a1..3bf1dbadab69 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));
From: Hyunchul Lee hyc.lee@gmail.com
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 <exfat>/ mount -o remount,ro <exfat>
the <exfat>/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.
Fixes: 719c1e182916 ("exfat: add super block operations") Cc: stable@vger.kernel.org # v5.7 Signed-off-by: Hyunchul Lee hyc.lee@gmail.com Acked-by: Sungjong Seo sj1557.seo@samsung.com Signed-off-by: Namjae Jeon namjae.jeon@samsung.com --- fs/exfat/super.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/fs/exfat/super.c b/fs/exfat/super.c index c1b1ed306a48..e87980153398 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)
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 kohada.t2@gmail.com Reviewed-by: Sungjong Seo sj1557.seo@samsung.com Signed-off-by: Namjae Jeon namjae.jeon@samsung.com --- 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 3bf1dbadab69..2c9c78317721 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,
From: Sungjong Seo sj1557.seo@samsung.com
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.
Fixes: 98d917047e8b ("exfat: add file operations") Cc: stable@vger.kernel.org # v5.7 Signed-off-by: Sungjong Seo sj1557.seo@samsung.com Signed-off-by: Namjae Jeon namjae.jeon@samsung.com --- 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 349ca0c282c2..6db302d76d4c 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 d67fb8a6f770..d865050fa6cd 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 5b4ddff18731..b93aa9e6cb16 100644 --- a/fs/exfat/file.c +++ b/fs/exfat/file.c @@ -6,6 +6,7 @@ #include <linux/slab.h> #include <linux/cred.h> #include <linux/buffer_head.h> +#include <linux/blkdev.h>
#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, };
Hi Namjae,
On Thu, Jul 02, 2020 at 08:20:19AM +0900, Namjae Jeon wrote:
Could you please push exfat stable patches into 5.7.y kernel tree ?
I've queued them up, however it would be much easier if for commits that don't require any modification to allow backporting you would just provide the commit ids in Linus's tree rather than the patches themselves.
I do see that you had to modify this one:
Sungjong Seo (1): exfat: flush dirty metadata in fsync
In which case, a header in the commit message indicating the upstream commit id would be appriciated. Something like this:
[ Upstream commit 5267456e953fd8c5abd8e278b1cc6a9f9027ac0a ]
Thank you!
Hi Namjae,
Hi Sasha,
On Thu, Jul 02, 2020 at 08:20:19AM +0900, Namjae Jeon wrote:
Could you please push exfat stable patches into 5.7.y kernel tree ?
I've queued them up, however it would be much easier if for commits that don't require any modification to allow backporting you would just provide the commit ids in Linus's tree rather than the patches themselves.
I do see that you had to modify this one:
Sungjong Seo (1): exfat: flush dirty metadata in fsync
In which case, a header in the commit message indicating the upstream commit id would be appriciated. Something like this:
Okay, I'll do that next time! Thank you!
[ Upstream commit 5267456e953fd8c5abd8e278b1cc6a9f9027ac0a ]
Thank you!
-- Thanks, Sasha
linux-stable-mirror@lists.linaro.org