Skip to content

Commit

Permalink
fs: exfat: Update exFAT driver
Browse files Browse the repository at this point in the history
git-repository: https://github.com/namjaejeon/linux-exfat-oot.git
Date: Mar 1, 2024
Last commit: exfat: fix appending discontinuous clusters to empty file

Note:
Your device didn't come with exFat, you can't add extra official support, you can't include something that doesn't have it in stock, that's for Lineage (their device requirements) only.

SDFat is old, so let's move on to something more up-to-date and with better performance.

Signed-off-by: TogoFire <togofire@mailfence.com>
Change-Id: I0b72418fa6adaed4cfcdacf41e33b3c72bba558a
  • Loading branch information
TogoFire committed Sep 14, 2024
1 parent 28cc5e1 commit 40cf112
Show file tree
Hide file tree
Showing 12 changed files with 361 additions and 754 deletions.
19 changes: 8 additions & 11 deletions fs/exfat/.github/workflows/c-cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: linux-exfat-oot CI

on:
push:
branches: [ "for-kernel-version-from-4.1.0" ]
branches: [ "master" ]
pull_request:
branches: [ "for-kernel-version-from-4.1.0" ]
branches: [ "master" ]

jobs:
build:
Expand All @@ -17,10 +17,10 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install libelf-dev wget tar gzip python2.7
wget https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/linux-4.1.36.tar.gz
tar xf linux-4.1.36.tar.gz
mv linux-4.1.36 linux-stable
rm -rf linux-4.1.36.tar.gz
wget https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.15.140.tar.gz
tar xf linux-5.15.140.tar.gz
mv linux-5.15.140 linux-stable
rm -rf linux-5.15.140.tar.gz
- name: Prerequisite for xfstests testing
run: |
sudo apt-get install linux-headers-$(uname -r)
Expand All @@ -35,17 +35,14 @@ jobs:
- name: Copy exfat source to kernel
run: |
mv linux-stable ../
mkdir ../linux-stable/fs/exfat
cp -ar * ../linux-stable/fs/exfat/
- name: Compile with 4.1 kernel
- name: Compile with 5.15 kernel
run: |
cd ../linux-stable
yes "" | make oldconfig > /dev/null
echo 'obj-$(CONFIG_EXFAT_FS) += exfat/' >> fs/Makefile
echo 'source "fs/exfat/Kconfig"' >> fs/Kconfig
echo 'CONFIG_EXFAT_FS=m' >> .config
echo 'CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8"' >> .config
make -j$((`nproc`+1)) fs/exfat/exfat.ko
make KBUILD_MODPOST_WARN=1 KBUILD_MODPOST_NOFINAL=1 fs/exfat/exfat.ko
- name: Run xfstests testsuite
run: |
cd ..
Expand Down
5 changes: 3 additions & 2 deletions fs/exfat/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## exFAT filesystem
This is the exfat filesystem for support from the linux 4.1 kernel
to the latest kernel.
This is the exfat filesystem for support from the linux 5.15 kernel
to the latest kernel. If you want to use exfat from 4.1 ~ 5.15 kernel,
Please use #for-kernel-version-from-4.1.0 branch.

## Installing as a stand-alone module

Expand Down
12 changes: 0 additions & 12 deletions fs/exfat/balloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@
#include <linux/slab.h>
#include <linux/bitmap.h>
#include <linux/buffer_head.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
#include <linux/sched/signal.h>
#else
#include <linux/sched.h>
#endif
#include <linux/vmalloc.h>

#include "exfat_raw.h"
Expand All @@ -30,10 +26,6 @@
#error "BITS_PER_LONG not 32 or 64"
#endif

#ifndef ALIGN_DOWN
#define ALIGN_DOWN(x, a) __ALIGN_KERNEL((x) - ((a) - 1), (a))
#endif

/*
* Allocation Bitmap Management Functions
*/
Expand Down Expand Up @@ -61,12 +53,8 @@ static int exfat_allocate_bitmap(struct super_block *sb,
}
sbi->map_sectors = ((need_map_size - 1) >>
(sb->s_blocksize_bits)) + 1;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
sbi->vol_amap = kvmalloc_array(sbi->map_sectors,
sizeof(struct buffer_head *), GFP_KERNEL);
#else
sbi->vol_amap = vmalloc(sbi->map_sectors * sizeof(struct buffer_head *));
#endif
if (!sbi->vol_amap)
return -ENOMEM;

Expand Down
8 changes: 0 additions & 8 deletions fs/exfat/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -461,19 +461,11 @@ int exfat_init_dir_entry(struct inode *inode, struct exfat_chain *p_dir,
{
struct super_block *sb = inode->i_sb;
struct exfat_sb_info *sbi = EXFAT_SB(sb);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
struct timespec64 ts;
#else
struct timespec ts;
#endif
struct exfat_dentry *ep;
struct buffer_head *bh;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
ts = current_time(inode);
#else
ts = CURRENT_TIME_SEC;
#endif

/*
* We cannot use exfat_get_dentry_set here because file ep is not
Expand Down
31 changes: 2 additions & 29 deletions fs/exfat/exfat_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,16 +220,11 @@ struct exfat_dir_entry {
unsigned char flags;
unsigned short attr;
loff_t size;
loff_t valid_size;
unsigned int num_subdirs;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
struct timespec64 atime;
struct timespec64 mtime;
struct timespec64 crtime;
#else
struct timespec atime;
struct timespec mtime;
struct timespec crtime;
#endif
struct exfat_dentry_namebuf namebuf;
};

Expand Down Expand Up @@ -337,17 +332,14 @@ struct exfat_inode_info {
loff_t i_size_aligned;
/* on-disk position of directory entry or 0 */
loff_t i_pos;
loff_t valid_size;
/* hash by i_location */
struct hlist_node i_hash_fat;
/* protect bmap against truncate */
struct rw_semaphore truncate_lock;
struct inode vfs_inode;
/* File creation time */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
struct timespec64 i_crtime;
#else
struct timespec i_crtime;
#endif
};

static inline struct exfat_sb_info *EXFAT_SB(struct super_block *sb)
Expand Down Expand Up @@ -477,7 +469,6 @@ extern const struct file_operations exfat_file_operations;
int __exfat_truncate(struct inode *inode);
void exfat_truncate(struct inode *inode);

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)
int exfat_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
struct iattr *attr);
Expand All @@ -491,16 +482,6 @@ int exfat_getattr(struct user_namespace *mnt_userns, const struct path *path,
struct kstat *stat, unsigned int request_mask,
unsigned int query_flags);
#endif
#else
int exfat_setattr(struct dentry *dentry, struct iattr *attr);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
int exfat_getattr(const struct path *path, struct kstat *stat,
unsigned int request_mask, unsigned int query_flags);
#else
int exfat_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat);
#endif
#endif
int exfat_file_fsync(struct file *file, loff_t start, loff_t end, int datasync);
long exfat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
long exfat_compat_ioctl(struct file *filp, unsigned int cmd,
Expand Down Expand Up @@ -593,7 +574,6 @@ void __exfat_fs_error(struct super_block *sb, int report, const char *fmt, ...)
#define exfat_debug(sb, fmt, ...) \
pr_debug("exFAT-fs (%s): " fmt "\n", (sb)->s_id, ##__VA_ARGS__)

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
void exfat_get_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts,
u8 tz, __le16 time, __le16 date, u8 time_cs);
void exfat_truncate_atime(struct timespec64 *ts);
Expand All @@ -602,13 +582,6 @@ void exfat_truncate_inode_atime(struct inode *inode);
#endif
void exfat_set_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts,
u8 *tz, __le16 *time, __le16 *date, u8 *time_cs);
#else
void exfat_get_entry_time(struct exfat_sb_info *sbi, struct timespec *ts,
u8 tz, __le16 time, __le16 date, u8 time_cs);
void exfat_truncate_atime(struct timespec *ts);
void exfat_set_entry_time(struct exfat_sb_info *sbi, struct timespec *ts,
u8 *tz, __le16 *time, __le16 *date, u8 *time_cs);
#endif
u16 exfat_calc_chksum16(void *data, int len, u16 chksum, int type);
u32 exfat_calc_chksum32(void *data, int len, u32 chksum, int type);
void exfat_update_bh(struct buffer_head *bh, int sync);
Expand Down
8 changes: 0 additions & 8 deletions fs/exfat/fatent.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@ static int exfat_mirror_bh(struct super_block *sb, sector_t sec,
memcpy(c_bh->b_data, bh->b_data, sb->s_blocksize);
set_buffer_uptodate(c_bh);
mark_buffer_dirty(c_bh);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
if (sb->s_flags & SB_SYNCHRONOUS)
#else
if (sb->s_flags & MS_SYNCHRONOUS)
#endif
err = sync_dirty_buffer(c_bh);
brelse(c_bh);
}
Expand Down Expand Up @@ -80,11 +76,7 @@ int exfat_ent_set(struct super_block *sb, unsigned int loc,

fat_entry = (__le32 *)&(bh->b_data[off]);
*fat_entry = cpu_to_le32(content);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
exfat_update_bh(bh, sb->s_flags & SB_SYNCHRONOUS);
#else
exfat_update_bh(bh, sb->s_flags & MS_SYNCHRONOUS);
#endif
exfat_mirror_bh(sb, sec, bh);
brelse(bh);
return 0;
Expand Down
Loading

0 comments on commit 40cf112

Please sign in to comment.