Commit edb543cf authored by Linus Torvalds's avatar Linus Torvalds

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
parents 615bc218 5267456e
...@@ -309,7 +309,7 @@ const struct file_operations exfat_dir_operations = { ...@@ -309,7 +309,7 @@ const struct file_operations exfat_dir_operations = {
.llseek = generic_file_llseek, .llseek = generic_file_llseek,
.read = generic_read_dir, .read = generic_read_dir,
.iterate = exfat_iterate, .iterate = exfat_iterate,
.fsync = generic_file_fsync, .fsync = exfat_file_fsync,
}; };
int exfat_alloc_new_dir(struct inode *inode, struct exfat_chain *clu) 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, ...@@ -425,10 +425,12 @@ static void exfat_init_name_entry(struct exfat_dentry *ep,
ep->dentry.name.flags = 0x0; ep->dentry.name.flags = 0x0;
for (i = 0; i < EXFAT_FILE_NAME_LEN; i++) { for (i = 0; i < EXFAT_FILE_NAME_LEN; i++) {
if (*uniname != 0x0) {
ep->dentry.name.unicode_0_14[i] = cpu_to_le16(*uniname); ep->dentry.name.unicode_0_14[i] = cpu_to_le16(*uniname);
if (*uniname == 0x0)
break;
uniname++; uniname++;
} else {
ep->dentry.name.unicode_0_14[i] = 0x0;
}
} }
} }
......
...@@ -420,6 +420,7 @@ void exfat_truncate(struct inode *inode, loff_t size); ...@@ -420,6 +420,7 @@ void exfat_truncate(struct inode *inode, loff_t size);
int exfat_setattr(struct dentry *dentry, struct iattr *attr); int exfat_setattr(struct dentry *dentry, struct iattr *attr);
int exfat_getattr(const struct path *path, struct kstat *stat, int exfat_getattr(const struct path *path, struct kstat *stat,
unsigned int request_mask, unsigned int query_flags); 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 */ /* namei.c */
extern const struct dentry_operations exfat_dentry_ops; extern const struct dentry_operations exfat_dentry_ops;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/cred.h> #include <linux/cred.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/blkdev.h>
#include "exfat_raw.h" #include "exfat_raw.h"
#include "exfat_fs.h" #include "exfat_fs.h"
...@@ -346,12 +347,28 @@ int exfat_setattr(struct dentry *dentry, struct iattr *attr) ...@@ -346,12 +347,28 @@ int exfat_setattr(struct dentry *dentry, struct iattr *attr)
return error; 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);
}
const struct file_operations exfat_file_operations = { const struct file_operations exfat_file_operations = {
.llseek = generic_file_llseek, .llseek = generic_file_llseek,
.read_iter = generic_file_read_iter, .read_iter = generic_file_read_iter,
.write_iter = generic_file_write_iter, .write_iter = generic_file_write_iter,
.mmap = generic_file_mmap, .mmap = generic_file_mmap,
.fsync = generic_file_fsync, .fsync = exfat_file_fsync,
.splice_read = generic_file_splice_read, .splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write, .splice_write = iter_file_splice_write,
}; };
......
...@@ -975,7 +975,6 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry) ...@@ -975,7 +975,6 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
goto unlock; goto unlock;
} }
exfat_set_vol_flags(sb, VOL_DIRTY);
exfat_chain_set(&clu_to_free, ei->start_clu, exfat_chain_set(&clu_to_free, ei->start_clu,
EXFAT_B_TO_CLU_ROUND_UP(i_size_read(inode), sbi), ei->flags); EXFAT_B_TO_CLU_ROUND_UP(i_size_read(inode), sbi), ei->flags);
...@@ -1002,6 +1001,7 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry) ...@@ -1002,6 +1001,7 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
num_entries++; num_entries++;
brelse(bh); brelse(bh);
exfat_set_vol_flags(sb, VOL_DIRTY);
err = exfat_remove_entries(dir, &cdir, entry, 0, num_entries); err = exfat_remove_entries(dir, &cdir, entry, 0, num_entries);
if (err) { if (err) {
exfat_err(sb, "failed to exfat_remove_entries : err(%d)", err); 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, ...@@ -1077,10 +1077,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, epold = exfat_get_dentry(sb, p_dir, oldentry + 1, &old_bh,
&sector_old); &sector_old);
if (!epold)
return -EIO;
epnew = exfat_get_dentry(sb, p_dir, newentry + 1, &new_bh, epnew = exfat_get_dentry(sb, p_dir, newentry + 1, &new_bh,
&sector_new); &sector_new);
if (!epold || !epnew) if (!epnew) {
brelse(old_bh);
return -EIO; return -EIO;
}
memcpy(epnew, epold, DENTRY_SIZE); memcpy(epnew, epold, DENTRY_SIZE);
exfat_update_bh(sb, new_bh, sync); exfat_update_bh(sb, new_bh, sync);
...@@ -1161,10 +1165,14 @@ static int exfat_move_file(struct inode *inode, struct exfat_chain *p_olddir, ...@@ -1161,10 +1165,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, epmov = exfat_get_dentry(sb, p_olddir, oldentry + 1, &mov_bh,
&sector_mov); &sector_mov);
if (!epmov)
return -EIO;
epnew = exfat_get_dentry(sb, p_newdir, newentry + 1, &new_bh, epnew = exfat_get_dentry(sb, p_newdir, newentry + 1, &new_bh,
&sector_new); &sector_new);
if (!epmov || !epnew) if (!epnew) {
brelse(mov_bh);
return -EIO; return -EIO;
}
memcpy(epnew, epmov, DENTRY_SIZE); memcpy(epnew, epmov, DENTRY_SIZE);
exfat_update_bh(sb, new_bh, IS_DIRSYNC(inode)); exfat_update_bh(sb, new_bh, IS_DIRSYNC(inode));
......
...@@ -693,10 +693,20 @@ static void exfat_free(struct fs_context *fc) ...@@ -693,10 +693,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 = { static const struct fs_context_operations exfat_context_ops = {
.parse_param = exfat_parse_param, .parse_param = exfat_parse_param,
.get_tree = exfat_get_tree, .get_tree = exfat_get_tree,
.free = exfat_free, .free = exfat_free,
.reconfigure = exfat_reconfigure,
}; };
static int exfat_init_fs_context(struct fs_context *fc) static int exfat_init_fs_context(struct fs_context *fc)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment