summaryrefslogtreecommitdiff
path: root/fs/exfat/super.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-09-24 15:26:04 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2024-09-24 15:26:04 -0700
commit4165cee7ecb112c20bc1a05fa8d93d16d11b68c2 (patch)
tree950eaf556b5d4fc6868acae1f3005705592f762b /fs/exfat/super.c
parent79952bdcbcea53e57c2ca97e7448f8a6bdb6106a (diff)
parentcb7d85014fb1ca3387f7ff5f6067337b3d7f3c5a (diff)
Merge tag 'exfat-for-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat
Pull exfat updates from Namjae Jeon: - Clean-up unnecessary codes as ->valid_size is supported - buffered-IO fallback is no longer needed when using direct-IO - Move ->valid_size extension from mmap to ->page_mkwrite. This improves the overhead caused by unnecessary zero-out during mmap. - Fix memleaks from exfat_load_bitmap() and exfat_create_upcase_table() - Add sops->shutdown and ioctl - Add Yuezhang Mo as a reviwer * tag 'exfat-for-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat: MAINTAINERS: exfat: add myself as reviewer exfat: resolve memory leak from exfat_create_upcase_table() exfat: move extend valid_size into ->page_mkwrite() exfat: fix memory leak in exfat_load_bitmap() exfat: Implement sops->shutdown and ioctl exfat: do not fallback to buffered write exfat: drop ->i_size_ondisk
Diffstat (limited to 'fs/exfat/super.c')
-rw-r--r--fs/exfat/super.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/fs/exfat/super.c b/fs/exfat/super.c
index 323ecebe6f0e..bd57844414aa 100644
--- a/fs/exfat/super.c
+++ b/fs/exfat/super.c
@@ -46,6 +46,9 @@ static int exfat_sync_fs(struct super_block *sb, int wait)
struct exfat_sb_info *sbi = EXFAT_SB(sb);
int err = 0;
+ if (unlikely(exfat_forced_shutdown(sb)))
+ return 0;
+
if (!wait)
return 0;
@@ -167,6 +170,41 @@ static int exfat_show_options(struct seq_file *m, struct dentry *root)
return 0;
}
+int exfat_force_shutdown(struct super_block *sb, u32 flags)
+{
+ int ret;
+ struct exfat_sb_info *sbi = sb->s_fs_info;
+ struct exfat_mount_options *opts = &sbi->options;
+
+ if (exfat_forced_shutdown(sb))
+ return 0;
+
+ switch (flags) {
+ case EXFAT_GOING_DOWN_DEFAULT:
+ case EXFAT_GOING_DOWN_FULLSYNC:
+ ret = bdev_freeze(sb->s_bdev);
+ if (ret)
+ return ret;
+ bdev_thaw(sb->s_bdev);
+ set_bit(EXFAT_FLAGS_SHUTDOWN, &sbi->s_exfat_flags);
+ break;
+ case EXFAT_GOING_DOWN_NOSYNC:
+ set_bit(EXFAT_FLAGS_SHUTDOWN, &sbi->s_exfat_flags);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (opts->discard)
+ opts->discard = 0;
+ return 0;
+}
+
+static void exfat_shutdown(struct super_block *sb)
+{
+ exfat_force_shutdown(sb, EXFAT_GOING_DOWN_NOSYNC);
+}
+
static struct inode *exfat_alloc_inode(struct super_block *sb)
{
struct exfat_inode_info *ei;
@@ -193,6 +231,7 @@ static const struct super_operations exfat_sops = {
.sync_fs = exfat_sync_fs,
.statfs = exfat_statfs,
.show_options = exfat_show_options,
+ .shutdown = exfat_shutdown,
};
enum {
@@ -370,8 +409,6 @@ static int exfat_read_root(struct inode *inode)
inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9;
ei->i_pos = ((loff_t)sbi->root_dir << 32) | 0xffffffff;
- ei->i_size_aligned = i_size_read(inode);
- ei->i_size_ondisk = i_size_read(inode);
exfat_save_attr(inode, EXFAT_ATTR_SUBDIR);
ei->i_crtime = simple_inode_init_ts(inode);