Skip to content

Commit 5267456

Browse files
Sungjong Seonamjaejeon
authored andcommitted
exfat: flush dirty metadata in fsync
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 <[email protected]> Signed-off-by: Namjae Jeon <[email protected]>
1 parent 3bcfb70 commit 5267456

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

fs/exfat/dir.c

Lines changed: 1 addition & 1 deletion
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)

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
};

0 commit comments

Comments
 (0)