fs: sdfat: Update to version 2.1.8

Taken from SM-G965F_PP_Opensource kernel (G965FXXU2CRLI)
This commit is contained in:
derfelot 2019-01-06 00:33:53 +01:00 committed by ShevT
parent 9bdd1f4409
commit 55e113b7c0
17 changed files with 280 additions and 152 deletions

View File

@ -1311,4 +1311,3 @@ u32 amap_get_au_stat(struct super_block *sb, s32 mode)
return 0;
}

View File

@ -478,6 +478,13 @@ void fsapi_invalidate_extent(struct inode *inode)
}
EXPORT_SYMBOL(fsapi_invalidate_extent);
/* check device is ejected */
s32 fsapi_check_bdi_valid(struct super_block *sb)
{
return fscore_check_bdi_valid(sb);
}
EXPORT_SYMBOL(fsapi_check_bdi_valid);
#ifdef CONFIG_SDFAT_DFR

View File

@ -355,6 +355,9 @@ u32 fsapi_get_au_stat(struct super_block *sb, s32 mode);
/* extent cache functions */
void fsapi_invalidate_extent(struct inode *inode);
/* bdev management */
s32 fsapi_check_bdi_valid(struct super_block *sb);
#ifdef CONFIG_SDFAT_DFR
/*----------------------------------------------------------------------*/
/* Defragmentation related */

View File

@ -838,5 +838,4 @@ static void __dcache_remove_hash(cache_ent_t *bp)
__remove_from_hash(bp);
}
/* end of cache.c */

View File

@ -1621,6 +1621,12 @@ s32 fscore_shutdown(void)
return 0;
}
/* check device is ejected */
s32 fscore_check_bdi_valid(struct super_block *sb)
{
return bdev_check_bdi_valid(sb);
}
static bool is_exfat(pbr_t *pbr)
{
int i = 53;
@ -1703,6 +1709,7 @@ s32 fscore_mount(struct super_block *sb)
pbr_t *p_pbr;
struct buffer_head *tmp_bh = NULL;
struct gendisk *disk = sb->s_bdev->bd_disk;
struct hd_struct *part = sb->s_bdev->bd_part;
struct sdfat_mount_options *opts = &(SDFAT_SB(sb)->options);
FS_INFO_T *fsi = &(SDFAT_SB(sb)->fsi);
@ -1802,9 +1809,11 @@ free_bh:
"misaligned" : "aligned");
sdfat_log_msg(sb, KERN_INFO,
"detected volume size : %llu MB (disk_size : %llu MB)",
fsi->num_sectors >> 11,
disk ? (u64)((disk->part0.nr_sects) >> 11) : 0);
"detected volume size : %llu KB (disk : %llu KB, "
"part : %llu KB)",
(fsi->num_sectors * (sb->s_blocksize >> SECTOR_SIZE_BITS)) >> 1,
disk ? (u64)((disk->part0.nr_sects) >> 1) : 0,
part ? (u64)((part->nr_sects) >> 1) : 0);
ret = load_upcase_table(sb);
if (ret) {

View File

@ -70,6 +70,9 @@ typedef struct {
s32 fscore_init(void);
s32 fscore_shutdown(void);
/* bdev management */
s32 fscore_check_bdi_valid(struct super_block *sb);
/* chain management */
s32 chain_cont_cluster(struct super_block *sb, u32 chain, u32 len);

View File

@ -733,8 +733,8 @@ static s32 __extract_uni_name_from_name_entry(NAME_DENTRY_T *ep, u16 *uniname, s
static s32 exfat_find_dir_entry(struct super_block *sb, FILE_ID_T *fid,
CHAIN_T *p_dir, UNI_NAME_T *p_uniname, s32 num_entries, DOS_NAME_T *unused, u32 type)
{
s32 i, rewind = 0, dentry = 0, end_eidx = 0, num_ext = 0, len;
s32 order, step, name_len;
s32 i, rewind = 0, dentry = 0, end_eidx = 0, num_ext = 0, len = 0;
s32 order, step, name_len = 0;
s32 dentries_per_clu, num_empty = 0;
u32 entry_type;
u16 entry_uniname[16], *uniname = NULL, unichar;

View File

@ -1323,8 +1323,9 @@ static sector_t __calc_hidden_sect(struct super_block *sb)
hidden = bdev->bd_part->start_sect;
/* a disk device, not a partition */
if (!hidden) {
ASSERT(bdev == bdev->bd_contains);
ASSERT(!bdev->bd_part->partno);
if (bdev != bdev->bd_contains)
sdfat_log_msg(sb, KERN_WARNING,
"hidden(0), but disk has a partition table");
goto out;
}
@ -1334,8 +1335,8 @@ static sector_t __calc_hidden_sect(struct super_block *sb)
}
out:
sdfat_log_msg(sb, KERN_INFO, "start_sect of partition : %lld",
(s64)hidden);
sdfat_log_msg(sb, KERN_INFO, "start_sect of part(%d) : %lld",
bdev ? bdev->bd_part->partno : -1, (s64)hidden);
return hidden;
}

View File

@ -1368,5 +1368,4 @@ defrag_spo_test(
}
#endif /* CONFIG_SDFAT_DFR_DEBUG */
#endif /* CONFIG_SDFAT_DFR */

View File

@ -258,4 +258,3 @@ void defrag_spo_test(struct super_block *sb, int flag, const char *caller);
#endif /* CONFIG_SDFAT_DFR */
#endif /* _SDFAT_DEFRAG_H */

View File

@ -43,11 +43,23 @@
#include "version.h"
#ifdef CONFIG_SDFAT_SUPPORT_STLOG
#ifdef CONFIG_PROC_FSLOG
#include <linux/fslog.h>
#else
#include <linux/stlog.h>
#endif
#else
#define ST_LOG(fmt, ...)
#endif
/*************************************************************************
* FUNCTIONS WHICH HAS KERNEL VERSION DEPENDENCY
*************************************************************************/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
#define CURRENT_TIME_SEC timespec_trunc(current_kernel_time(), NSEC_PER_SEC)
#endif
/*
* sdfat_fs_error reports a file system problem that might indicate fa data
* corruption/inconsistency. Depending on 'errors' mount option the
@ -84,6 +96,7 @@ void __sdfat_fs_error(struct super_block *sb, int report, const char *fmt, ...)
sb->s_id, MAJOR(bd_dev), MINOR(bd_dev));
} else if (opts->errors == SDFAT_ERRORS_RO && !(sb->s_flags & MS_RDONLY)) {
sb->s_flags |= MS_RDONLY;
sdfat_statistics_set_mnt_ro();
pr_err("[SDFAT](%s[%d:%d]): Filesystem has been set "
"read-only\n", sb->s_id, MAJOR(bd_dev), MINOR(bd_dev));
#ifdef CONFIG_SDFAT_SUPPORT_STLOG
@ -253,15 +266,9 @@ void sdfat_time_unix2fat(struct sdfat_sb_info *sbi, struct timespec *ts,
TIMESTAMP_T *tm_now(struct sdfat_sb_info *sbi, TIMESTAMP_T *tp)
{
struct timespec ts;
struct timespec ts = CURRENT_TIME_SEC;
DATE_TIME_T dt;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0)
ts = CURRENT_TIME_SEC;
#else
ktime_get_real_ts(&ts);
#endif
sdfat_time_unix2fat(sbi, &ts, &dt);
tp->year = dt.Year;

View File

@ -78,6 +78,27 @@ static void __mpage_write_end_io(struct bio *bio, int err);
/*************************************************************************
* FUNCTIONS WHICH HAS KERNEL VERSION DEPENDENCY
*************************************************************************/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
/* EMPTY */
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) */
static inline void bio_set_dev(struct bio *bio, struct block_device *bdev)
{
bio->bi_bdev = bdev;
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
static inline void __sdfat_clean_bdev_aliases(struct block_device *bdev, sector_t block)
{
clean_bdev_aliases(bdev, block, 1);
}
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0) */
static inline void __sdfat_clean_bdev_aliases(struct block_device *bdev, sector_t block)
{
unmap_underlying_metadata(bdev, block);
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
static inline void __sdfat_submit_bio_write2(int flags, struct bio *bio)
{
@ -91,24 +112,6 @@ static inline void __sdfat_submit_bio_write2(int flags, struct bio *bio)
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)
static void mpage_write_end_io(struct bio *bio)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
__mpage_write_end_io(bio, bio->bi_status);
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) */
__mpage_write_end_io(bio, bio->bi_error);
#endif
}
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4,3,0) */
static void mpage_write_end_io(struct bio *bio, int err)
{
if (test_bit(BIO_UPTODATE, &bio->bi_flags))
err = 0;
__mpage_write_end_io(bio, err);
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
static inline int bio_get_nr_vecs(struct block_device *bdev)
{
@ -160,6 +163,28 @@ static inline void __sdfat_set_bio_size(struct bio *bio, unsigned int size)
}
#endif
/*************************************************************************
* MORE FUNCTIONS WHICH HAS KERNEL VERSION DEPENDENCY
*************************************************************************/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
static void mpage_write_end_io(struct bio *bio)
{
__mpage_write_end_io(bio, blk_status_to_errno(bio->bi_status));
}
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)
static void mpage_write_end_io(struct bio *bio)
{
__mpage_write_end_io(bio, bio->bi_error);
}
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4,3,0) */
static void mpage_write_end_io(struct bio *bio, int err)
{
if (test_bit(BIO_UPTODATE, &bio->bi_flags))
err = 0;
__mpage_write_end_io(bio, err);
}
#endif
/* __check_dfr_on() and __dfr_writepage_end_io() functions
* are copied from sdfat.c
* Each function should be same perfectly
@ -281,11 +306,7 @@ mpage_alloc(struct block_device *bdev,
}
if (bio) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
bio_set_dev(bio, bdev);
#else
bio->bi_bdev = bdev;
#endif
__sdfat_set_bio_sector(bio, first_sector);
}
return bio;
@ -369,11 +390,7 @@ static int sdfat_mpage_writepage(struct page *page,
if (buffer_new(bh)) {
clear_buffer_new(bh);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
clean_bdev_bh_alias(bh);
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) */
unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr);
#endif
__sdfat_clean_bdev_aliases(bh->b_bdev, bh->b_blocknr);
}
}
@ -423,12 +440,7 @@ static int sdfat_mpage_writepage(struct page *page,
goto confused;
if (buffer_new(&map_bh))
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
clean_bdev_bh_alias(&map_bh);
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) */
unmap_underlying_metadata(map_bh.b_bdev,
map_bh.b_blocknr);
#endif
__sdfat_clean_bdev_aliases(map_bh.b_bdev, map_bh.b_blocknr);
if (buffer_boundary(&map_bh)) {
boundary_block = map_bh.b_blocknr;
boundary_bdev = map_bh.b_bdev;

View File

@ -68,9 +68,6 @@
/* skip iterating emit_dots when dir is empty */
#define ITER_POS_FILLED_DOTS (2)
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0)
#define current_time(x) (CURRENT_TIME_SEC)
#endif
/* type index declare at sdfat.h */
const char *FS_TYPE_STR[] = {
"auto",
@ -112,6 +109,7 @@ static void sdfat_free_namebuf(DENTRY_NAMEBUF_T *nb);
/*************************************************************************
* INNER FUNCTIONS FOR FUNCTIONS WHICH HAS KERNEL VERSION DEPENDENCY
*************************************************************************/
static int __sdfat_getattr(struct inode *inode, struct kstat *stat);
static void __sdfat_writepage_end_io(struct bio *bio, int err);
static inline void __lock_super(struct super_block *sb);
static inline void __unlock_super(struct super_block *sb);
@ -140,6 +138,51 @@ static int __sdfat_cmpi(const struct dentry *dentry, unsigned int len,
/*************************************************************************
* FUNCTIONS WHICH HAS KERNEL VERSION DEPENDENCY
*************************************************************************/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
/* EMPTY */
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) */
static inline void bio_set_dev(struct bio *bio, struct block_device *bdev)
{
bio->bi_bdev = bdev;
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
#define CURRENT_TIME_SEC timespec_trunc(current_kernel_time(), NSEC_PER_SEC)
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
static int sdfat_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int query_flags)
{
struct inode *inode = d_backing_inode(path->dentry);
return __sdfat_getattr(inode, stat);
}
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) */
static int sdfat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
{
struct inode *inode = dentry->d_inode;
return __sdfat_getattr(inode, stat);
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
static inline void __sdfat_clean_bdev_aliases(struct block_device *bdev, sector_t block)
{
clean_bdev_aliases(bdev, block, 1);
}
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0) */
static inline void __sdfat_clean_bdev_aliases(struct block_device *bdev, sector_t block)
{
unmap_underlying_metadata(bdev, block);
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
static int sdfat_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
@ -219,25 +262,6 @@ static inline void inode_unlock(struct inode *inode)
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)
static void sdfat_writepage_end_io(struct bio *bio)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
__sdfat_writepage_end_io(bio, bio->bi_status);
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) */
__sdfat_writepage_end_io(bio, bio->bi_error);
#endif
}
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0) */
static void sdfat_writepage_end_io(struct bio *bio, int err)
{
if (test_bit(BIO_UPTODATE, &bio->bi_flags))
err = 0;
__sdfat_writepage_end_io(bio, err);
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
static inline int sdfat_remount_syncfs(struct super_block *sb)
{
@ -870,6 +894,26 @@ static int sdfat_file_fsync(struct file *filp, int datasync)
/*************************************************************************
* MORE FUNCTIONS WHICH HAS KERNEL VERSION DEPENDENCY
*************************************************************************/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
static void sdfat_writepage_end_io(struct bio *bio)
{
__sdfat_writepage_end_io(bio, blk_status_to_errno(bio->bi_status));
}
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)
static void sdfat_writepage_end_io(struct bio *bio)
{
__sdfat_writepage_end_io(bio, bio->bi_error);
}
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0) */
static void sdfat_writepage_end_io(struct bio *bio, int err)
{
if (test_bit(BIO_UPTODATE, &bio->bi_flags))
err = 0;
__sdfat_writepage_end_io(bio, err);
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
static int sdfat_cmp(const struct dentry *dentry,
unsigned int len, const char *str, const struct qstr *name)
@ -910,30 +954,6 @@ static int sdfat_cmpi(const struct dentry *parent, const struct inode *pinode,
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
static const char *sdfat_follow_link(struct dentry *dentry, struct inode *inode, struct delayed_call *done)
{
struct sdfat_inode_info *ei = SDFAT_I(inode);
return (char *)(ei->target);
}
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
static const char *sdfat_follow_link(struct dentry *dentry, void **cookie)
{
struct sdfat_inode_info *ei = SDFAT_I(dentry->d_inode);
return *cookie = (char *)(ei->target);
}
#else
static void *sdfat_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct sdfat_inode_info *ei = SDFAT_I(dentry->d_inode);
nd_set_link(nd, (char *)(ei->target));
return NULL;
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
static ssize_t sdfat_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
@ -1041,6 +1061,31 @@ static inline ssize_t __sdfat_blkdev_direct_IO(int rw, struct kiocb *iocb,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
static const char *sdfat_follow_link(struct dentry *dentry, struct inode *inode, struct delayed_call *done)
{
struct sdfat_inode_info *ei = SDFAT_I(inode);
return (char *)(ei->target);
}
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
static const char *sdfat_follow_link(struct dentry *dentry, void **cookie)
{
struct sdfat_inode_info *ei = SDFAT_I(dentry->d_inode);
return *cookie = (char *)(ei->target);
}
#else
static void *sdfat_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct sdfat_inode_info *ei = SDFAT_I(dentry->d_inode);
nd_set_link(nd, (char *)(ei->target));
return NULL;
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
static int sdfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
bool excl)
@ -2221,6 +2266,16 @@ static long sdfat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned lo
return sdfat_dbg_ioctl(inode, filp, cmd, arg);
}
static int __sdfat_getattr(struct inode *inode, struct kstat *stat)
{
TMSG("%s entered\n", __func__);
generic_fillattr(inode, stat);
stat->blksize = SDFAT_SB(inode->i_sb)->fsi.cluster_size;
TMSG("%s exited\n", __func__);
return 0;
}
static void __sdfat_writepage_end_io(struct bio *bio, int err)
{
@ -2313,6 +2368,7 @@ static int __sdfat_create(struct inode *dir, struct dentry *dentry)
{
struct super_block *sb = dir->i_sb;
struct inode *inode;
struct timespec ts;
FILE_ID_T fid;
loff_t i_pos;
int err;
@ -2321,6 +2377,8 @@ static int __sdfat_create(struct inode *dir, struct dentry *dentry)
TMSG("%s entered\n", __func__);
ts = CURRENT_TIME_SEC;
err = fsapi_create(dir, (u8 *) dentry->d_name.name, FM_REGULAR, &fid);
if (err)
goto out;
@ -2328,7 +2386,7 @@ static int __sdfat_create(struct inode *dir, struct dentry *dentry)
__lock_d_revalidate(dentry);
dir->i_version++;
dir->i_ctime = dir->i_mtime = dir->i_atime = current_time(dir);
dir->i_ctime = dir->i_mtime = dir->i_atime = ts;
if (IS_DIRSYNC(dir))
(void) sdfat_sync_inode(dir);
else
@ -2341,7 +2399,7 @@ static int __sdfat_create(struct inode *dir, struct dentry *dentry)
goto out;
}
inode->i_version++;
inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
inode->i_mtime = inode->i_atime = inode->i_ctime = ts;
/* timestamp is already written, so mark_inode_dirty() is unneeded. */
d_instantiate(dentry, inode);
@ -2475,12 +2533,15 @@ static int sdfat_unlink(struct inode *dir, struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
struct super_block *sb = dir->i_sb;
struct timespec ts;
int err;
__lock_super(sb);
TMSG("%s entered\n", __func__);
ts = CURRENT_TIME_SEC;
SDFAT_I(inode)->fid.size = i_size_read(inode);
__cancel_dfr_work(inode, 0, SDFAT_I(inode)->fid.size, __func__);
@ -2492,14 +2553,14 @@ static int sdfat_unlink(struct inode *dir, struct dentry *dentry)
__lock_d_revalidate(dentry);
dir->i_version++;
dir->i_mtime = dir->i_atime = current_time(dir);
dir->i_mtime = dir->i_atime = ts;
if (IS_DIRSYNC(dir))
(void) sdfat_sync_inode(dir);
else
mark_inode_dirty(dir);
clear_nlink(inode);
inode->i_mtime = inode->i_atime = current_time(inode);
inode->i_mtime = inode->i_atime = ts;
sdfat_detach(inode);
dentry->d_time = dir->i_version;
out:
@ -2513,6 +2574,7 @@ static int sdfat_symlink(struct inode *dir, struct dentry *dentry, const char *t
{
struct super_block *sb = dir->i_sb;
struct inode *inode;
struct timespec ts;
FILE_ID_T fid;
loff_t i_pos;
int err;
@ -2527,6 +2589,8 @@ static int sdfat_symlink(struct inode *dir, struct dentry *dentry, const char *t
TMSG("%s entered\n", __func__);
ts = CURRENT_TIME_SEC;
err = fsapi_create(dir, (u8 *) dentry->d_name.name, FM_SYMLINK, &fid);
if (err)
goto out;
@ -2541,7 +2605,7 @@ static int sdfat_symlink(struct inode *dir, struct dentry *dentry, const char *t
__lock_d_revalidate(dentry);
dir->i_version++;
dir->i_ctime = dir->i_mtime = dir->i_atime = current_time(dir);
dir->i_ctime = dir->i_mtime = dir->i_atime = ts;
if (IS_DIRSYNC(dir))
(void) sdfat_sync_inode(dir);
else
@ -2554,7 +2618,7 @@ static int sdfat_symlink(struct inode *dir, struct dentry *dentry, const char *t
goto out;
}
inode->i_version++;
inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
inode->i_mtime = inode->i_atime = inode->i_ctime = ts;
/* timestamp is already written, so mark_inode_dirty() is unneeded. */
SDFAT_I(inode)->target = kmalloc((len+1), GFP_KERNEL);
@ -2577,6 +2641,7 @@ static int __sdfat_mkdir(struct inode *dir, struct dentry *dentry)
{
struct super_block *sb = dir->i_sb;
struct inode *inode;
struct timespec ts;
FILE_ID_T fid;
loff_t i_pos;
int err;
@ -2585,6 +2650,8 @@ static int __sdfat_mkdir(struct inode *dir, struct dentry *dentry)
TMSG("%s entered\n", __func__);
ts = CURRENT_TIME_SEC;
err = fsapi_mkdir(dir, (u8 *) dentry->d_name.name, &fid);
if (err)
goto out;
@ -2592,7 +2659,7 @@ static int __sdfat_mkdir(struct inode *dir, struct dentry *dentry)
__lock_d_revalidate(dentry);
dir->i_version++;
dir->i_ctime = dir->i_mtime = dir->i_atime = current_time(dir);
dir->i_ctime = dir->i_mtime = dir->i_atime = ts;
if (IS_DIRSYNC(dir))
(void) sdfat_sync_inode(dir);
else
@ -2606,7 +2673,7 @@ static int __sdfat_mkdir(struct inode *dir, struct dentry *dentry)
goto out;
}
inode->i_version++;
inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
inode->i_mtime = inode->i_atime = inode->i_ctime = ts;
/* timestamp is already written, so mark_inode_dirty() is unneeded. */
d_instantiate(dentry, inode);
@ -2625,12 +2692,15 @@ static int sdfat_rmdir(struct inode *dir, struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
struct super_block *sb = dir->i_sb;
struct timespec ts;
int err;
__lock_super(sb);
TMSG("%s entered\n", __func__);
ts = CURRENT_TIME_SEC;
SDFAT_I(inode)->fid.size = i_size_read(inode);
err = fsapi_rmdir(dir, &(SDFAT_I(inode)->fid));
@ -2640,7 +2710,7 @@ static int sdfat_rmdir(struct inode *dir, struct dentry *dentry)
__lock_d_revalidate(dentry);
dir->i_version++;
dir->i_mtime = dir->i_atime = current_time(dir);
dir->i_mtime = dir->i_atime = ts;
if (IS_DIRSYNC(dir))
(void) sdfat_sync_inode(dir);
else
@ -2648,7 +2718,7 @@ static int sdfat_rmdir(struct inode *dir, struct dentry *dentry)
drop_nlink(dir);
clear_nlink(inode);
inode->i_mtime = inode->i_atime = current_time(inode);
inode->i_mtime = inode->i_atime = ts;
sdfat_detach(inode);
dentry->d_time = dir->i_version;
out:
@ -2663,6 +2733,7 @@ static int __sdfat_rename(struct inode *old_dir, struct dentry *old_dentry,
{
struct inode *old_inode, *new_inode;
struct super_block *sb = old_dir->i_sb;
struct timespec ts;
loff_t i_pos;
int err;
@ -2673,6 +2744,8 @@ static int __sdfat_rename(struct inode *old_dir, struct dentry *old_dentry,
old_inode = old_dentry->d_inode;
new_inode = new_dentry->d_inode;
ts = CURRENT_TIME_SEC;
SDFAT_I(old_inode)->fid.size = i_size_read(old_inode);
__cancel_dfr_work(old_inode, 0, 1, __func__);
@ -2685,7 +2758,7 @@ static int __sdfat_rename(struct inode *old_dir, struct dentry *old_dentry,
__lock_d_revalidate(new_dentry);
new_dir->i_version++;
new_dir->i_ctime = new_dir->i_mtime = new_dir->i_atime = current_time(new_dir);
new_dir->i_ctime = new_dir->i_mtime = new_dir->i_atime = ts;
if (IS_DIRSYNC(new_dir))
(void) sdfat_sync_inode(new_dir);
else
@ -2706,7 +2779,7 @@ static int __sdfat_rename(struct inode *old_dir, struct dentry *old_dentry,
}
old_dir->i_version++;
old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir);
old_dir->i_ctime = old_dir->i_mtime = ts;
if (IS_DIRSYNC(old_dir))
(void) sdfat_sync_inode(old_dir);
else
@ -2725,7 +2798,7 @@ static int __sdfat_rename(struct inode *old_dir, struct dentry *old_dentry,
__func__);
WARN_ON(new_inode->i_nlink == 0);
}
new_inode->i_ctime = current_time(new_inode);
new_inode->i_ctime = ts;
#if 0
(void) sdfat_sync_inode(new_inode);
#endif
@ -2749,7 +2822,7 @@ static int sdfat_cont_expand(struct inode *inode, loff_t size)
if (err)
return err;
inode->i_ctime = inode->i_mtime = current_time(inode);
inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
mark_inode_dirty(inode);
if (!IS_SYNC(inode))
@ -2882,25 +2955,6 @@ static int sdfat_setattr(struct dentry *dentry, struct iattr *attr)
return error;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
static int sdfat_getattr(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags)
{
struct inode *inode = path->dentry->d_inode;
#else
static int sdfat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
{
struct inode *inode = dentry->d_inode;
#endif
TMSG("%s entered\n", __func__);
generic_fillattr(inode, stat);
stat->blksize = SDFAT_SB(inode->i_sb)->fsi.cluster_size;
TMSG("%s exited\n", __func__);
return 0;
}
static const struct inode_operations sdfat_dir_inode_operations = {
.create = sdfat_create,
.lookup = sdfat_lookup,
@ -3010,7 +3064,7 @@ static void sdfat_truncate(struct inode *inode, loff_t old_size)
if (err)
goto out;
inode->i_ctime = inode->i_mtime = current_time(inode);
inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
if (IS_DIRSYNC(inode))
(void) sdfat_sync_inode(inode);
else
@ -3107,7 +3161,7 @@ static int sdfat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
if (((fsi->vol_type == FAT12) || (fsi->vol_type == FAT16)) &&
(inode->i_ino == SDFAT_ROOT_INO)) {
if (sector < (fsi->dentries_in_root >>
(sb->s_blocksize_bits-DENTRY_SIZE_BITS))) {
(sb->s_blocksize_bits - DENTRY_SIZE_BITS))) {
*phys = sector + fsi->root_start_sector;
*mapped_blocks = 1;
}
@ -3216,7 +3270,17 @@ static int sdfat_da_prep_block(struct inode *inode, sector_t iblock,
} else if (create == 1) {
/* Not exist: new cluster needed */
BUG_ON(!BLOCK_ADDED(bmap_create));
if (!BLOCK_ADDED(bmap_create)) {
sector_t last_block;
last_block = (i_size_read(inode) + (sb->s_blocksize - 1))
>> sb->s_blocksize_bits;
sdfat_fs_error(sb, "%s: new cluster need, but "
"bmap_create == BMAP_NOT_CREATE(iblock:%lld, "
"last_block:%lld)", __func__,
(s64)iblock, (s64)last_block);
err = -EIO;
goto unlock_ret;
}
// Reserved Cluster (only if iblock is the first sector in a clu)
if (sec_offset == 0) {
@ -3444,11 +3508,7 @@ static inline void sdfat_submit_fullpage_bio(struct block_device *bdev,
*/
bio = bio_alloc(GFP_NOIO, 1);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
bio_set_dev(bio, bdev);
#else
bio->bi_bdev = bdev;
#endif
bio->bi_vcnt = 1;
bio->bi_io_vec[0].bv_page = page; /* Inline vec */
bio->bi_io_vec[0].bv_len = length; /* PAGE_SIZE */
@ -3539,11 +3599,7 @@ static int sdfat_writepage(struct page *page, struct writeback_control *wbc)
if (buffer_new(bh)) {
clear_buffer_new(bh);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
clean_bdev_bh_alias(bh);
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) */
unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr);
#endif
__sdfat_clean_bdev_aliases(bh->b_bdev, bh->b_blocknr);
}
}
@ -3593,7 +3649,7 @@ static int sdfat_writepage(struct page *page, struct writeback_control *wbc)
atomic_inc(&SDFAT_SB(sb)->stat_n_pages_queued);
sdfat_submit_fullpage_bio(head->b_bdev,
head->b_blocknr << (inode->i_blkbits - sb->s_blocksize_bits),
head->b_blocknr << (sb->s_blocksize_bits - SECTOR_SIZE_BITS),
nr_blocks_towrite << inode->i_blkbits,
page);
@ -3655,16 +3711,32 @@ static void sdfat_write_failed(struct address_space *mapping, loff_t to)
}
}
static int sdfat_check_writable(struct super_block *sb)
{
if (fsapi_check_bdi_valid(sb))
return -EIO;
if (sb->s_flags & MS_RDONLY)
return -EROFS;
return 0;
}
static int __sdfat_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned int len,
unsigned int flags, struct page **pagep,
void **fsdata, get_block_t *get_block,
loff_t *bytes, const char *fname)
{
struct super_block *sb = mapping->host->i_sb;
int ret;
__cancel_dfr_work(mapping->host, pos, (loff_t)(pos + len), fname);
ret = sdfat_check_writable(sb);
if (unlikely(ret < 0))
return ret;
*pagep = NULL;
ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
get_block, bytes);
@ -3719,7 +3791,7 @@ static int sdfat_write_end(struct file *file, struct address_space *mapping,
sdfat_write_failed(mapping, pos+len);
if (!(err < 0) && !(fid->attr & ATTR_ARCHIVE)) {
inode->i_mtime = inode->i_ctime = current_time(inode);
inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
fid->attr |= ATTR_ARCHIVE;
mark_inode_dirty(inode);
}
@ -4725,9 +4797,12 @@ static int sdfat_read_root(struct inode *inode)
{
struct super_block *sb = inode->i_sb;
struct sdfat_sb_info *sbi = SDFAT_SB(sb);
struct timespec ts;
FS_INFO_T *fsi = &(sbi->fsi);
DIR_ENTRY_T info;
ts = CURRENT_TIME_SEC;
SDFAT_I(inode)->fid.dir.dir = fsi->root_dir;
SDFAT_I(inode)->fid.dir.flags = 0x01;
SDFAT_I(inode)->fid.entry = -1;
@ -4763,7 +4838,7 @@ static int sdfat_read_root(struct inode *inode)
SDFAT_I(inode)->i_size_ondisk = i_size_read(inode);
sdfat_save_attr(inode, ATTR_SUBDIR);
inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
inode->i_mtime = inode->i_atime = inode->i_ctime = ts;
set_nlink(inode, info.NumSubdirs + 2);
return 0;
}
@ -5004,6 +5079,7 @@ static struct file_system_type sdfat_fs_type = {
#endif /* CONFIG_SDFAT_DBG_IOCTL */
.fs_flags = FS_REQUIRES_DEV,
};
MODULE_ALIAS_FS("sdfat");
#ifdef CONFIG_SDFAT_USE_FOR_EXFAT
static struct file_system_type exfat_fs_type = {
@ -5017,6 +5093,7 @@ static struct file_system_type exfat_fs_type = {
#endif /* CONFIG_SDFAT_DBG_IOCTL */
.fs_flags = FS_REQUIRES_DEV,
};
MODULE_ALIAS_FS("exfat");
#endif /* CONFIG_SDFAT_USE_FOR_EXFAT */
#ifdef CONFIG_SDFAT_USE_FOR_VFAT
@ -5031,6 +5108,7 @@ static struct file_system_type vfat_fs_type = {
#endif /* CONFIG_SDFAT_DBG_IOCTL */
.fs_flags = FS_REQUIRES_DEV,
};
MODULE_ALIAS_FS("vfat");
#endif /* CONFIG_SDFAT_USE_FOR_VFAT */
static int __init init_sdfat_fs(void)
@ -5116,6 +5194,7 @@ static void __exit exit_sdfat_fs(void)
sdfat_destroy_inodecache();
unregister_filesystem(&sdfat_fs_type);
#ifdef CONFIG_SDFAT_USE_FOR_EXFAT
unregister_filesystem(&exfat_fs_type);
#endif /* CONFIG_SDFAT_USE_FOR_EXFAT */

View File

@ -127,7 +127,7 @@ struct sdfat_mount_options {
unsigned char errors; /* on error: continue, panic, remount-ro */
unsigned char discard; /* flag on if -o dicard specified and device support discard() */
unsigned char fs_type; /* fs_type that user specified */
unsigned short adj_req; /* support aligned mpage write */
unsigned short adj_req; /* support aligned mpage write */
};
#define SDFAT_HASH_BITS 8
@ -301,6 +301,7 @@ static inline void sdfat_save_attr(struct inode *inode, u32 attr)
extern int sdfat_statistics_init(struct kset *sdfat_kset);
extern void sdfat_statistics_uninit(void);
extern void sdfat_statistics_set_mnt(FS_INFO_T *fsi);
extern void sdfat_statistics_set_mnt_ro(void);
extern void sdfat_statistics_set_mkdir(u8 flags);
extern void sdfat_statistics_set_create(u8 flags);
extern void sdfat_statistics_set_rw(u8 flags, u32 clu_offset, s32 create);
@ -313,6 +314,7 @@ static inline int sdfat_statistics_init(struct kset *sdfat_kset)
}
static inline void sdfat_statistics_uninit(void) {};
static inline void sdfat_statistics_set_mnt(FS_INFO_T *fsi) {};
static inline void sdfat_statistics_set_mnt_ro(void) {};
static inline void sdfat_statistics_set_mkdir(u8 flags) {};
static inline void sdfat_statistics_set_create(u8 flags) {};
static inline void sdfat_statistics_set_rw(u8 flags, u32 clu_offset, s32 create) {};
@ -505,4 +507,3 @@ extern void __sdfat_dmsg(int level, const char *fmt, ...) __printf(2, 3) __cold;
}
#endif /* !_SDFAT_H */

View File

@ -68,6 +68,8 @@
#define MAX_NAME_LENGTH 255 // max len of file name excluding NULL
#define DOS_NAME_LENGTH 11 // DOS file name length excluding NULL
#define SECTOR_SIZE_BITS 9 /* VFS sector size is 512 bytes */
#define DENTRY_SIZE 32 /* directory entry size */
#define DENTRY_SIZE_BITS 5

View File

@ -8,6 +8,7 @@ enum {
SDFAT_MNT_FAT16,
SDFAT_MNT_FAT32,
SDFAT_MNT_EXFAT,
SDFAT_MNT_RO,
SDFAT_MNT_MAX
};
@ -85,11 +86,12 @@ static ssize_t mount_show(struct kobject *kobj,
{
return snprintf(buff, PAGE_SIZE, "\"FAT12_MNT_I\":\"%u\","
"\"FAT16_MNT_I\":\"%u\",\"FAT32_MNT_I\":\"%u\","
"\"EXFAT_MNT_I\":\"%u\"\n",
"\"EXFAT_MNT_I\":\"%u\",\"RO_MNT_I\":\"%u\"\n",
statistics.mnt_cnt[SDFAT_MNT_FAT12],
statistics.mnt_cnt[SDFAT_MNT_FAT16],
statistics.mnt_cnt[SDFAT_MNT_FAT32],
statistics.mnt_cnt[SDFAT_MNT_EXFAT]);
statistics.mnt_cnt[SDFAT_MNT_EXFAT],
statistics.mnt_cnt[SDFAT_MNT_RO]);
}
static ssize_t nofat_op_show(struct kobject *kobj,
@ -201,6 +203,11 @@ void sdfat_statistics_set_mnt(FS_INFO_T *fsi)
statistics.clus_vfat[SDFAT_VF_CLUS_MAX - 1]++;
}
void sdfat_statistics_set_mnt_ro(void)
{
statistics.mnt_cnt[SDFAT_MNT_RO]++;
}
void sdfat_statistics_set_mkdir(u8 flags)
{
if (flags != 0x03)

View File

@ -22,4 +22,5 @@
/* PURPOSE : sdFAT File Manager */
/* */
/************************************************************************/
#define SDFAT_VERSION "2.0.8-lineage"
#define SDFAT_VERSION "2.1.8-lineage"