Skip to content

Commit

Permalink
Merge tag 'exfat-for-5.17-rc1' of git://git.kernel.org/pub/scm/linux/…
Browse files Browse the repository at this point in the history
…kernel/git/linkinjeon/exfat

Pull exfat updates from Namjae Jeon:

 - Fix ->i_blocks truncation issue that still exists elsewhere.

 - Four cleanups & typos fixes.

 - Move super block magic number to magic.h

 - Fix missing REQ_SYNC in exfat_update_bhs().

* tag 'exfat-for-5.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat:
  exfat: fix missing REQ_SYNC in exfat_update_bhs()
  exfat: remove argument 'sector' from exfat_get_dentry()
  exfat: move super block magic number to magic.h
  exfat: fix i_blocks for files truncated over 4 GiB
  exfat: reuse exfat_inode_info variable instead of calling EXFAT_I()
  exfat: make exfat_find_location() static
  exfat: fix typos in comments
  exfat: simplify is_valid_cluster()
  • Loading branch information
Linus Torvalds committed Jan 16, 2022
2 parents 175398a + 3d96652 commit 88db845
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 87 deletions.
2 changes: 1 addition & 1 deletion fs/exfat/balloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ int exfat_load_bitmap(struct super_block *sb)
struct exfat_dentry *ep;
struct buffer_head *bh;

ep = exfat_get_dentry(sb, &clu, i, &bh, NULL);
ep = exfat_get_dentry(sb, &clu, i, &bh);
if (!ep)
return -EIO;

Expand Down
42 changes: 17 additions & 25 deletions fs/exfat/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
{
int i, dentries_per_clu, dentries_per_clu_bits = 0, num_ext;
unsigned int type, clu_offset, max_dentries;
sector_t sector;
struct exfat_chain dir, clu;
struct exfat_uni_name uni_name;
struct exfat_dentry *ep;
Expand Down Expand Up @@ -115,7 +114,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
i = dentry & (dentries_per_clu - 1);

for ( ; i < dentries_per_clu; i++, dentry++) {
ep = exfat_get_dentry(sb, &clu, i, &bh, &sector);
ep = exfat_get_dentry(sb, &clu, i, &bh);
if (!ep)
return -EIO;

Expand Down Expand Up @@ -156,7 +155,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
dir_entry->namebuf.lfnbuf_len);
brelse(bh);

ep = exfat_get_dentry(sb, &clu, i + 1, &bh, NULL);
ep = exfat_get_dentry(sb, &clu, i + 1, &bh);
if (!ep)
return -EIO;
dir_entry->size =
Expand Down Expand Up @@ -445,15 +444,14 @@ 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);
struct timespec64 ts = current_time(inode);
sector_t sector;
struct exfat_dentry *ep;
struct buffer_head *bh;

/*
* We cannot use exfat_get_dentry_set here because file ep is not
* initialized yet.
*/
ep = exfat_get_dentry(sb, p_dir, entry, &bh, &sector);
ep = exfat_get_dentry(sb, p_dir, entry, &bh);
if (!ep)
return -EIO;

Expand All @@ -477,7 +475,7 @@ int exfat_init_dir_entry(struct inode *inode, struct exfat_chain *p_dir,
exfat_update_bh(bh, IS_DIRSYNC(inode));
brelse(bh);

ep = exfat_get_dentry(sb, p_dir, entry + 1, &bh, &sector);
ep = exfat_get_dentry(sb, p_dir, entry + 1, &bh);
if (!ep)
return -EIO;

Expand All @@ -496,20 +494,19 @@ int exfat_update_dir_chksum(struct inode *inode, struct exfat_chain *p_dir,
struct super_block *sb = inode->i_sb;
int ret = 0;
int i, num_entries;
sector_t sector;
u16 chksum;
struct exfat_dentry *ep, *fep;
struct buffer_head *fbh, *bh;

fep = exfat_get_dentry(sb, p_dir, entry, &fbh, &sector);
fep = exfat_get_dentry(sb, p_dir, entry, &fbh);
if (!fep)
return -EIO;

num_entries = fep->dentry.file.num_ext + 1;
chksum = exfat_calc_chksum16(fep, DENTRY_SIZE, 0, CS_DIR_ENTRY);

for (i = 1; i < num_entries; i++) {
ep = exfat_get_dentry(sb, p_dir, entry + i, &bh, NULL);
ep = exfat_get_dentry(sb, p_dir, entry + i, &bh);
if (!ep) {
ret = -EIO;
goto release_fbh;
Expand All @@ -531,21 +528,20 @@ int exfat_init_ext_entry(struct inode *inode, struct exfat_chain *p_dir,
{
struct super_block *sb = inode->i_sb;
int i;
sector_t sector;
unsigned short *uniname = p_uniname->name;
struct exfat_dentry *ep;
struct buffer_head *bh;
int sync = IS_DIRSYNC(inode);

ep = exfat_get_dentry(sb, p_dir, entry, &bh, &sector);
ep = exfat_get_dentry(sb, p_dir, entry, &bh);
if (!ep)
return -EIO;

ep->dentry.file.num_ext = (unsigned char)(num_entries - 1);
exfat_update_bh(bh, sync);
brelse(bh);

ep = exfat_get_dentry(sb, p_dir, entry + 1, &bh, &sector);
ep = exfat_get_dentry(sb, p_dir, entry + 1, &bh);
if (!ep)
return -EIO;

Expand All @@ -555,7 +551,7 @@ int exfat_init_ext_entry(struct inode *inode, struct exfat_chain *p_dir,
brelse(bh);

for (i = EXFAT_FIRST_CLUSTER; i < num_entries; i++) {
ep = exfat_get_dentry(sb, p_dir, entry + i, &bh, &sector);
ep = exfat_get_dentry(sb, p_dir, entry + i, &bh);
if (!ep)
return -EIO;

Expand All @@ -574,12 +570,11 @@ int exfat_remove_entries(struct inode *inode, struct exfat_chain *p_dir,
{
struct super_block *sb = inode->i_sb;
int i;
sector_t sector;
struct exfat_dentry *ep;
struct buffer_head *bh;

for (i = order; i < num_entries; i++) {
ep = exfat_get_dentry(sb, p_dir, entry + i, &bh, &sector);
ep = exfat_get_dentry(sb, p_dir, entry + i, &bh);
if (!ep)
return -EIO;

Expand Down Expand Up @@ -656,8 +651,8 @@ static int exfat_walk_fat_chain(struct super_block *sb,
return 0;
}

int exfat_find_location(struct super_block *sb, struct exfat_chain *p_dir,
int entry, sector_t *sector, int *offset)
static int exfat_find_location(struct super_block *sb, struct exfat_chain *p_dir,
int entry, sector_t *sector, int *offset)
{
int ret;
unsigned int off, clu = 0;
Expand Down Expand Up @@ -717,8 +712,7 @@ static int exfat_dir_readahead(struct super_block *sb, sector_t sec)
}

struct exfat_dentry *exfat_get_dentry(struct super_block *sb,
struct exfat_chain *p_dir, int entry, struct buffer_head **bh,
sector_t *sector)
struct exfat_chain *p_dir, int entry, struct buffer_head **bh)
{
unsigned int dentries_per_page = EXFAT_B_TO_DEN(PAGE_SIZE);
int off;
Expand All @@ -740,8 +734,6 @@ struct exfat_dentry *exfat_get_dentry(struct super_block *sb,
if (!*bh)
return NULL;

if (sector)
*sector = sec;
return (struct exfat_dentry *)((*bh)->b_data + off);
}

Expand Down Expand Up @@ -892,7 +884,7 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
es->bh[es->num_bh++] = bh;
}

/* validiate cached dentries */
/* validate cached dentries */
for (i = 1; i < num_entries; i++) {
ep = exfat_get_dentry_cached(es, i);
if (!exfat_validate_entry(exfat_get_entry_type(ep), &mode))
Expand Down Expand Up @@ -960,7 +952,7 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
if (rewind && dentry == end_eidx)
goto not_found;

ep = exfat_get_dentry(sb, &clu, i, &bh, NULL);
ep = exfat_get_dentry(sb, &clu, i, &bh);
if (!ep)
return -EIO;

Expand Down Expand Up @@ -1145,7 +1137,7 @@ int exfat_count_ext_entries(struct super_block *sb, struct exfat_chain *p_dir,
struct buffer_head *bh;

for (i = 0, entry++; i < ep->dentry.file.num_ext; i++, entry++) {
ext_ep = exfat_get_dentry(sb, p_dir, entry, &bh, NULL);
ext_ep = exfat_get_dentry(sb, p_dir, entry, &bh);
if (!ext_ep)
return -EIO;

Expand Down Expand Up @@ -1175,7 +1167,7 @@ int exfat_count_dir_entries(struct super_block *sb, struct exfat_chain *p_dir)

while (clu.dir != EXFAT_EOF_CLUSTER) {
for (i = 0; i < dentries_per_clu; i++) {
ep = exfat_get_dentry(sb, &clu, i, &bh, NULL);
ep = exfat_get_dentry(sb, &clu, i, &bh);
if (!ep)
return -EIO;
entry_type = exfat_get_entry_type(ep);
Expand Down
6 changes: 1 addition & 5 deletions fs/exfat/exfat_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include <linux/ratelimit.h>
#include <linux/nls.h>

#define EXFAT_SUPER_MAGIC 0x2011BAB0UL
#define EXFAT_ROOT_INO 1

#define EXFAT_CLUSTERS_UNTRACKED (~0u)
Expand Down Expand Up @@ -459,11 +458,8 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname,
int num_entries, unsigned int type, struct exfat_hint *hint_opt);
int exfat_alloc_new_dir(struct inode *inode, struct exfat_chain *clu);
int exfat_find_location(struct super_block *sb, struct exfat_chain *p_dir,
int entry, sector_t *sector, int *offset);
struct exfat_dentry *exfat_get_dentry(struct super_block *sb,
struct exfat_chain *p_dir, int entry, struct buffer_head **bh,
sector_t *sector);
struct exfat_chain *p_dir, int entry, struct buffer_head **bh);
struct exfat_dentry *exfat_get_dentry_cached(struct exfat_entry_set_cache *es,
int num);
struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
Expand Down
4 changes: 1 addition & 3 deletions fs/exfat/fatent.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,7 @@ int exfat_ent_set(struct super_block *sb, unsigned int loc,
static inline bool is_valid_cluster(struct exfat_sb_info *sbi,
unsigned int clus)
{
if (clus < EXFAT_FIRST_CLUSTER || sbi->num_clusters <= clus)
return false;
return true;
return clus >= EXFAT_FIRST_CLUSTER && clus < sbi->num_clusters;
}

int exfat_ent_get(struct super_block *sb, unsigned int loc,
Expand Down
18 changes: 9 additions & 9 deletions fs/exfat/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,7 @@ int __exfat_truncate(struct inode *inode, loff_t new_size)
exfat_set_volume_dirty(sb);

num_clusters_new = EXFAT_B_TO_CLU_ROUND_UP(i_size_read(inode), sbi);
num_clusters_phys =
EXFAT_B_TO_CLU_ROUND_UP(EXFAT_I(inode)->i_size_ondisk, sbi);
num_clusters_phys = EXFAT_B_TO_CLU_ROUND_UP(ei->i_size_ondisk, sbi);

exfat_chain_set(&clu, ei->start_clu, num_clusters_phys, ei->flags);

Expand Down Expand Up @@ -228,12 +227,13 @@ void exfat_truncate(struct inode *inode, loff_t size)
{
struct super_block *sb = inode->i_sb;
struct exfat_sb_info *sbi = EXFAT_SB(sb);
struct exfat_inode_info *ei = EXFAT_I(inode);
unsigned int blocksize = i_blocksize(inode);
loff_t aligned_size;
int err;

mutex_lock(&sbi->s_lock);
if (EXFAT_I(inode)->start_clu == 0) {
if (ei->start_clu == 0) {
/*
* Empty start_clu != ~0 (not allocated)
*/
Expand All @@ -251,20 +251,20 @@ void exfat_truncate(struct inode *inode, loff_t size)
else
mark_inode_dirty(inode);

inode->i_blocks = ((i_size_read(inode) + (sbi->cluster_size - 1)) &
~(sbi->cluster_size - 1)) >> inode->i_blkbits;
inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >>
inode->i_blkbits;
write_size:
aligned_size = i_size_read(inode);
if (aligned_size & (blocksize - 1)) {
aligned_size |= (blocksize - 1);
aligned_size++;
}

if (EXFAT_I(inode)->i_size_ondisk > i_size_read(inode))
EXFAT_I(inode)->i_size_ondisk = aligned_size;
if (ei->i_size_ondisk > i_size_read(inode))
ei->i_size_ondisk = aligned_size;

if (EXFAT_I(inode)->i_size_aligned > i_size_read(inode))
EXFAT_I(inode)->i_size_aligned = aligned_size;
if (ei->i_size_aligned > i_size_read(inode))
ei->i_size_aligned = aligned_size;
mutex_unlock(&sbi->s_lock);
}

Expand Down
15 changes: 7 additions & 8 deletions fs/exfat/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ static int __exfat_write_inode(struct inode *inode, int sync)
return 0;

/*
* If the indode is already unlinked, there is no need for updating it.
* If the inode is already unlinked, there is no need for updating it.
*/
if (ei->dir.dir == DIR_DELETED)
return 0;
Expand Down Expand Up @@ -114,10 +114,9 @@ static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset,
unsigned int local_clu_offset = clu_offset;
unsigned int num_to_be_allocated = 0, num_clusters = 0;

if (EXFAT_I(inode)->i_size_ondisk > 0)
if (ei->i_size_ondisk > 0)
num_clusters =
EXFAT_B_TO_CLU_ROUND_UP(EXFAT_I(inode)->i_size_ondisk,
sbi);
EXFAT_B_TO_CLU_ROUND_UP(ei->i_size_ondisk, sbi);

if (clu_offset >= num_clusters)
num_to_be_allocated = clu_offset - num_clusters + 1;
Expand Down Expand Up @@ -416,10 +415,10 @@ static int exfat_write_end(struct file *file, struct address_space *mapping,

err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata);

if (EXFAT_I(inode)->i_size_aligned < i_size_read(inode)) {
if (ei->i_size_aligned < i_size_read(inode)) {
exfat_fs_error(inode->i_sb,
"invalid size(size(%llu) > aligned(%llu)\n",
i_size_read(inode), EXFAT_I(inode)->i_size_aligned);
i_size_read(inode), ei->i_size_aligned);
return -EIO;
}

Expand Down Expand Up @@ -603,8 +602,8 @@ static int exfat_fill_inode(struct inode *inode, struct exfat_dir_entry *info)

exfat_save_attr(inode, info->attr);

inode->i_blocks = ((i_size_read(inode) + (sbi->cluster_size - 1)) &
~((loff_t)sbi->cluster_size - 1)) >> inode->i_blkbits;
inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >>
inode->i_blkbits;
inode->i_mtime = info->mtime;
inode->i_ctime = info->mtime;
ei->i_crtime = info->crtime;
Expand Down
3 changes: 2 additions & 1 deletion fs/exfat/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/buffer_head.h>
#include <linux/blk_types.h>

#include "exfat_raw.h"
#include "exfat_fs.h"
Expand Down Expand Up @@ -180,7 +181,7 @@ int exfat_update_bhs(struct buffer_head **bhs, int nr_bhs, int sync)
set_buffer_uptodate(bhs[i]);
mark_buffer_dirty(bhs[i]);
if (sync)
write_dirty_buffer(bhs[i], 0);
write_dirty_buffer(bhs[i], REQ_SYNC);
}

for (i = 0; i < nr_bhs && sync; i++) {
Expand Down
Loading

0 comments on commit 88db845

Please sign in to comment.