Skip to content
This repository was archived by the owner on Jun 19, 2024. It is now read-only.

Commit

Permalink
Merge pull request #26 from Fede2782/sdfat-update
Browse files Browse the repository at this point in the history
fs: sdfat: Update to version 2.6.0 from P610XXS3FWD2
  • Loading branch information
Royna2544 authored May 12, 2024
2 parents ab9de9c + 6e541f0 commit 60cb3f1
Show file tree
Hide file tree
Showing 8 changed files with 342 additions and 119 deletions.
42 changes: 38 additions & 4 deletions fs/sdfat/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,18 @@ u8 *fcache_getblk(struct super_block *sb, u64 sec)
return NULL;
}
move_to_mru(bp, &fsi->fcache.lru_list);
return bp->bh->b_data;

if (likely(bp->bh->b_data))
return bp->bh->b_data;

sdfat_msg(sb, KERN_ERR,
"%s: no b_data (flag:0x%02x, sect:%llu), %s",
__func__, bp->flag, sec, bp->flag ? "EIO" : ",retry");

if (bp->flag)
return NULL;

__fcache_ent_discard(sb, bp);
}

bp = __fcache_get(sb);
Expand All @@ -227,7 +238,14 @@ u8 *fcache_getblk(struct super_block *sb, u64 sec)
return NULL;
}

return bp->bh->b_data;
if (likely(bp->bh->b_data))
return bp->bh->b_data;

sdfat_msg(sb, KERN_ERR,
"%s: no b_data after read (flag:0x%02x, sect:%llu)",
__func__, bp->flag, sec);

return NULL;
}

static inline int __mark_delayed_dirty(struct super_block *sb, cache_ent_t *bp)
Expand Down Expand Up @@ -567,7 +585,17 @@ u8 *dcache_getblk(struct super_block *sb, u64 sec)
if (!(bp->flag & KEEPBIT)) // already in keep list
move_to_mru(bp, &fsi->dcache.lru_list);

return bp->bh->b_data;
if (likely(bp->bh->b_data))
return bp->bh->b_data;

sdfat_msg(sb, KERN_ERR,
"%s: no b_data (flag:0x%02x, sect:%llu), %s",
__func__, bp->flag, sec, bp->flag ? "EIO" : ",retry");

if (bp->flag)
return NULL;

__dcache_ent_discard(sb, bp);
}

bp = __dcache_get(sb);
Expand All @@ -584,8 +612,14 @@ u8 *dcache_getblk(struct super_block *sb, u64 sec)
return NULL;
}

return bp->bh->b_data;
if (likely(bp->bh->b_data))
return bp->bh->b_data;

sdfat_msg(sb, KERN_ERR,
"%s: no b_data after read (flag:0x%02x, sect:%llu)",
__func__, bp->flag, sec);

return NULL;
}

s32 dcache_modify(struct super_block *sb, u64 sec)
Expand Down
22 changes: 18 additions & 4 deletions fs/sdfat/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@ static inline u64 inode_peek_iversion(struct inode *inode)
#endif


#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)
static u64 bdev_nr_sectors(struct block_device *bdev)
{
struct hd_struct *part = bdev->bd_part;

if (!part)
return 0;

return (u64)(part->nr_sects);
}
#endif


/*----------------------------------------------------------------------*/
/* Constant & Macro Definitions */
/*----------------------------------------------------------------------*/
Expand Down Expand Up @@ -388,6 +401,9 @@ static s32 __load_upcase_table(struct super_block *sb, u64 sector, u64 num_secto
* memset(upcase_table, 0, UTBL_COL_COUNT * sizeof(u16 *));
*/

/* trigger read upcase_table ahead */
bdev_readahead(sb, sector, num_sectors);

fsi->vol_utbl = upcase_table;
num_sectors += sector;

Expand Down Expand Up @@ -1725,7 +1741,6 @@ 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);

Expand Down Expand Up @@ -1822,9 +1837,8 @@ s32 fscore_mount(struct super_block *sb)
"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);

disk ? (u64)(get_capacity(disk) >> 1) : 0,
(u64)bdev_nr_sectors(sb->s_bdev) >> 1);
ret = load_upcase_table(sb);
if (ret) {
sdfat_log_msg(sb, KERN_ERR, "failed to load upcase table");
Expand Down
3 changes: 3 additions & 0 deletions fs/sdfat/core_exfat.c
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 +1086,9 @@ s32 load_alloc_bmp(struct super_block *sb)

sector = CLUS_TO_SECT(fsi, fsi->map_clu);

/* trigger read amap ahead */
bdev_readahead(sb, sector, fsi->map_sectors);

for (j = 0; j < fsi->map_sectors; j++) {
fsi->vol_amap[j] = NULL;
ret = read_sect(sb, sector+j, &(fsi->vol_amap[j]), 1);
Expand Down
44 changes: 32 additions & 12 deletions fs/sdfat/core_fat.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ static u32 __calc_default_au_size(struct super_block *sb)
* ex2) 16GB -> 8MB
* ex3) >= 32GB -> 16MB
*/
total_sect = disk->part0.nr_sects;
total_sect = get_capacity(disk);
est_au_size = total_sect >> 2;

/* au_size assumed that bytes per sector is 512 */
Expand Down Expand Up @@ -684,33 +684,36 @@ static s32 fat_find_dir_entry(struct super_block *sb, FILE_ID_T *fid,
EXT_DENTRY_T *ext_ep = (EXT_DENTRY_T *)ep;
u32 cur_ord = (u32)ext_ep->order;
u32 cur_chksum = (s32)ext_ep->checksum;
u32 new_lfn = (cur_ord & MSDOS_LAST_LFN);
s32 len = 13;
u16 unichar;

cur_ord &= ~(MSDOS_LAST_LFN);
num_empty = 0;
candi_empty.eidx = -1;

/* check invalid lfn order */
if (!cur_ord || (cur_ord > MAX_LFN_ORDER))
goto reset_dentry_set;

/* check whether new lfn or not */
if (cur_ord & MSDOS_LAST_LFN) {
cur_ord &= ~(MSDOS_LAST_LFN);
if (new_lfn) {
chksum = cur_chksum;
len = (13 * (cur_ord-1));
len = (13 * (cur_ord - 1));
uniname = (p_uniname->name + len);
lfn_ord = cur_ord + 1;
lfn_len = 0;

/* check minimum name length */
if (cur_ord &&
(len > p_uniname->name_len)) {
if (len > p_uniname->name_len) {
/* MISMATCHED NAME LENGTH */
lfn_len = -1;
}
len = 0;
}

/* invalid lfn order */
if (!cur_ord || (cur_ord > MAX_LFN_ORDER) ||
((cur_ord + 1) != lfn_ord))
/* check if lfn is a consecutive number */
if ((cur_ord + 1) != lfn_ord)
goto reset_dentry_set;

/* check checksum of directory entry set */
Expand Down Expand Up @@ -1354,6 +1357,23 @@ s32 mount_fat16(struct super_block *sb, pbr_t *p_pbr)
return 0;
} /* end of mount_fat16 */

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
static u8 bdev_get_partno(struct block_device *bdev)
{
return bdev->bd_partno;
}
#else
static struct block_device *bdev_whole(struct block_device *bdev)
{
return bdev->bd_contains;
}

static u8 bdev_get_partno(struct block_device *bdev)
{
return bdev->bd_part->partno;
}
#endif

static sector_t __calc_hidden_sect(struct super_block *sb)
{
struct block_device *bdev = sb->s_bdev;
Expand All @@ -1362,10 +1382,10 @@ static sector_t __calc_hidden_sect(struct super_block *sb)
if (!bdev)
goto out;

hidden = bdev->bd_part->start_sect;
hidden = get_start_sect(bdev);
/* a disk device, not a partition */
if (!hidden) {
if (bdev != bdev->bd_contains)
if (bdev != bdev_whole(bdev))
sdfat_log_msg(sb, KERN_WARNING,
"hidden(0), but disk has a partition table");
goto out;
Expand All @@ -1378,7 +1398,7 @@ static sector_t __calc_hidden_sect(struct super_block *sb)

out:
sdfat_log_msg(sb, KERN_INFO, "start_sect of part(%d) : %lld",
bdev ? bdev->bd_part->partno : -1, (s64)hidden);
bdev ? bdev_get_partno(bdev) : -1, (s64)hidden);
return hidden;

}
Expand Down
54 changes: 39 additions & 15 deletions fs/sdfat/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@
#include <linux/fs.h>
#include <linux/buffer_head.h>
#include <linux/time.h>
#include <linux/blkdev.h>
#include "sdfat.h"
#include "version.h"


#ifdef CONFIG_SDFAT_SUPPORT_STLOG
#ifdef CONFIG_PROC_FSLOG
#include <linux/fslog.h>
Expand All @@ -52,6 +54,14 @@
#define ST_LOG(fmt, ...)
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
#include <linux/ktime.h>
#ifndef _TIME_T
#define _TIME_T
typedef ktime_t time_t;
#endif
#endif

/*************************************************************************
* FUNCTIONS WHICH HAS KERNEL VERSION DEPENDENCY
*************************************************************************/
Expand Down Expand Up @@ -203,14 +213,28 @@ EXPORT_SYMBOL(sdfat_log_version);
#define SECS_PER_HOUR (60 * SECS_PER_MIN)
#define SECS_PER_DAY (24 * SECS_PER_HOUR)

/* do not use time_t directly to prevent compile errors on 32bit kernel */
#define time_do_div(ori, base) \
({ \
u64 __ori = ori; \
do_div(__ori, base); \
(time_t)__ori; \
})

#define time_do_mod(ori, base) \
({ \
u64 __ori = ori; \
(time_t)do_div(__ori, base); \
})

#define MAKE_LEAP_YEAR(leap_year, year) \
do { \
/* 2100 isn't leap year */ \
if (unlikely(year > NO_LEAP_YEAR_2100)) \
leap_year = ((year + 3) / 4) - 1; \
else \
leap_year = ((year + 3) / 4); \
} while (0)
({ \
/* 2100 isn't leap year */ \
if (unlikely(year > NO_LEAP_YEAR_2100)) \
leap_year = time_do_div((year + 3), 4) - 1; \
else \
leap_year = time_do_div((year + 3), 4); \
})

/* Linear day numbers of the respective 1sts in non-leap years. */
static time_t accum_days_in_year[] = {
Expand Down Expand Up @@ -298,8 +322,8 @@ void sdfat_time_unix2fat(struct sdfat_sb_info *sbi, sdfat_timespec_t *ts,
}
#endif

day = second / SECS_PER_DAY - DAYS_DELTA_DECADE;
year = day / 365;
day = time_do_div(second, SECS_PER_DAY) - DAYS_DELTA_DECADE;
year = time_do_div(day, 365);

MAKE_LEAP_YEAR(ld, year);
if (year * 365 + ld > day)
Expand All @@ -320,12 +344,12 @@ void sdfat_time_unix2fat(struct sdfat_sb_info *sbi, sdfat_timespec_t *ts,
}
day -= accum_days_in_year[month];

tp->Second = second % SECS_PER_MIN;
tp->Minute = (second / SECS_PER_MIN) % 60;
tp->Hour = (second / SECS_PER_HOUR) % 24;
tp->Day = day + 1;
tp->Month = month;
tp->Year = year;
tp->Second = (u16)time_do_mod(second, SECS_PER_MIN);
tp->Minute = (u16)time_do_mod(time_do_div(second, SECS_PER_MIN), 60);
tp->Hour = (u16)time_do_mod(time_do_div(second, SECS_PER_HOUR), 24);
tp->Day = (u16)(day + 1);
tp->Month = (u16)month;
tp->Year = (u16)year;
}

TIMESTAMP_T *tm_now(struct inode *inode, TIMESTAMP_T *tp)
Expand Down
7 changes: 6 additions & 1 deletion fs/sdfat/mpage.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,12 @@ static inline void __sdfat_submit_bio_write2(int flags, struct bio *bio)
}
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)
static inline int bio_get_nr_vecs(struct block_device *bdev)
{
return BIO_MAX_VECS;
}
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
static inline int bio_get_nr_vecs(struct block_device *bdev)
{
return BIO_MAX_PAGES;
Expand Down
Loading

0 comments on commit 60cb3f1

Please sign in to comment.