Skip to content

Commit edb543c

Browse files
committed
Merge tag 'exfat-for-5.8-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat
Pull exfat fixes from Namjae Jeon: - Zero out unused characters of FileName field to avoid a complaint from some fsck tool. - Fix memory leak on error paths. - Fix unnecessary VOL_DIRTY set when calling rmdir on non-empty directory. - Call sync_filesystem() for read-only remount (Fix generic/452 test in xfstests) - Add own fsync() to flush dirty metadata. * tag 'exfat-for-5.8-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat: exfat: flush dirty metadata in fsync exfat: move setting VOL_DIRTY over exfat_remove_entries() exfat: call sync_filesystem for read-only remount exfat: add missing brelse() calls on error paths exfat: Set the unused characters of FileName field to the value 0000h
2 parents 615bc21 + 5267456 commit edb543c

File tree

5 files changed

+47
-9
lines changed

5 files changed

+47
-9
lines changed

fs/exfat/dir.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ const struct file_operations exfat_dir_operations = {
309309
.llseek = generic_file_llseek,
310310
.read = generic_read_dir,
311311
.iterate = exfat_iterate,
312-
.fsync = generic_file_fsync,
312+
.fsync = exfat_file_fsync,
313313
};
314314

315315
int exfat_alloc_new_dir(struct inode *inode, struct exfat_chain *clu)
@@ -425,10 +425,12 @@ static void exfat_init_name_entry(struct exfat_dentry *ep,
425425
ep->dentry.name.flags = 0x0;
426426

427427
for (i = 0; i < EXFAT_FILE_NAME_LEN; i++) {
428-
ep->dentry.name.unicode_0_14[i] = cpu_to_le16(*uniname);
429-
if (*uniname == 0x0)
430-
break;
431-
uniname++;
428+
if (*uniname != 0x0) {
429+
ep->dentry.name.unicode_0_14[i] = cpu_to_le16(*uniname);
430+
uniname++;
431+
} else {
432+
ep->dentry.name.unicode_0_14[i] = 0x0;
433+
}
432434
}
433435
}
434436

fs/exfat/exfat_fs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ void exfat_truncate(struct inode *inode, loff_t size);
420420
int exfat_setattr(struct dentry *dentry, struct iattr *attr);
421421
int exfat_getattr(const struct path *path, struct kstat *stat,
422422
unsigned int request_mask, unsigned int query_flags);
423+
int exfat_file_fsync(struct file *file, loff_t start, loff_t end, int datasync);
423424

424425
/* namei.c */
425426
extern const struct dentry_operations exfat_dentry_ops;

fs/exfat/file.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <linux/slab.h>
77
#include <linux/cred.h>
88
#include <linux/buffer_head.h>
9+
#include <linux/blkdev.h>
910

1011
#include "exfat_raw.h"
1112
#include "exfat_fs.h"
@@ -346,12 +347,28 @@ int exfat_setattr(struct dentry *dentry, struct iattr *attr)
346347
return error;
347348
}
348349

350+
int exfat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
351+
{
352+
struct inode *inode = filp->f_mapping->host;
353+
int err;
354+
355+
err = __generic_file_fsync(filp, start, end, datasync);
356+
if (err)
357+
return err;
358+
359+
err = sync_blockdev(inode->i_sb->s_bdev);
360+
if (err)
361+
return err;
362+
363+
return blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL);
364+
}
365+
349366
const struct file_operations exfat_file_operations = {
350367
.llseek = generic_file_llseek,
351368
.read_iter = generic_file_read_iter,
352369
.write_iter = generic_file_write_iter,
353370
.mmap = generic_file_mmap,
354-
.fsync = generic_file_fsync,
371+
.fsync = exfat_file_fsync,
355372
.splice_read = generic_file_splice_read,
356373
.splice_write = iter_file_splice_write,
357374
};

fs/exfat/namei.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,6 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
975975
goto unlock;
976976
}
977977

978-
exfat_set_vol_flags(sb, VOL_DIRTY);
979978
exfat_chain_set(&clu_to_free, ei->start_clu,
980979
EXFAT_B_TO_CLU_ROUND_UP(i_size_read(inode), sbi), ei->flags);
981980

@@ -1002,6 +1001,7 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
10021001
num_entries++;
10031002
brelse(bh);
10041003

1004+
exfat_set_vol_flags(sb, VOL_DIRTY);
10051005
err = exfat_remove_entries(dir, &cdir, entry, 0, num_entries);
10061006
if (err) {
10071007
exfat_err(sb, "failed to exfat_remove_entries : err(%d)", err);
@@ -1077,10 +1077,14 @@ static int exfat_rename_file(struct inode *inode, struct exfat_chain *p_dir,
10771077

10781078
epold = exfat_get_dentry(sb, p_dir, oldentry + 1, &old_bh,
10791079
&sector_old);
1080+
if (!epold)
1081+
return -EIO;
10801082
epnew = exfat_get_dentry(sb, p_dir, newentry + 1, &new_bh,
10811083
&sector_new);
1082-
if (!epold || !epnew)
1084+
if (!epnew) {
1085+
brelse(old_bh);
10831086
return -EIO;
1087+
}
10841088

10851089
memcpy(epnew, epold, DENTRY_SIZE);
10861090
exfat_update_bh(sb, new_bh, sync);
@@ -1161,10 +1165,14 @@ static int exfat_move_file(struct inode *inode, struct exfat_chain *p_olddir,
11611165

11621166
epmov = exfat_get_dentry(sb, p_olddir, oldentry + 1, &mov_bh,
11631167
&sector_mov);
1168+
if (!epmov)
1169+
return -EIO;
11641170
epnew = exfat_get_dentry(sb, p_newdir, newentry + 1, &new_bh,
11651171
&sector_new);
1166-
if (!epmov || !epnew)
1172+
if (!epnew) {
1173+
brelse(mov_bh);
11671174
return -EIO;
1175+
}
11681176

11691177
memcpy(epnew, epmov, DENTRY_SIZE);
11701178
exfat_update_bh(sb, new_bh, IS_DIRSYNC(inode));

fs/exfat/super.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,10 +693,20 @@ static void exfat_free(struct fs_context *fc)
693693
}
694694
}
695695

696+
static int exfat_reconfigure(struct fs_context *fc)
697+
{
698+
fc->sb_flags |= SB_NODIRATIME;
699+
700+
/* volume flag will be updated in exfat_sync_fs */
701+
sync_filesystem(fc->root->d_sb);
702+
return 0;
703+
}
704+
696705
static const struct fs_context_operations exfat_context_ops = {
697706
.parse_param = exfat_parse_param,
698707
.get_tree = exfat_get_tree,
699708
.free = exfat_free,
709+
.reconfigure = exfat_reconfigure,
700710
};
701711

702712
static int exfat_init_fs_context(struct fs_context *fc)

0 commit comments

Comments
 (0)