Skip to content

Commit e103ece

Browse files
committed
Merge tag 'exfat-for-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat
Pull exfat updates from Namjae Jeon: - Handle vendor extension and allocation entries as unrecognized benign secondary entries - Fix wrong ->i_blocks on devices with non-512 byte sector - Add the check to avoid returning -EIO from exfat_readdir() at current position exceeding the directory size - Fix a bug that reach the end of the directory stream at a position not aligned with the dentry size - Redefine DIR_DELETED as 0xFFFFFFF7, the bad cluster number - Two cleanup fixes and fix cluster leakage in error handling * tag 'exfat-for-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat: exfat: fix the newly allocated clusters are not freed in error handling exfat: don't print error log in normal case exfat: remove unneeded code from exfat_alloc_cluster() exfat: handle unreconized benign secondary entries exfat: fix inode->i_blocks for non-512 byte sector size device exfat: redefine DIR_DELETED as the bad cluster number exfat: fix reporting fs error when reading dir beyond EOF exfat: fix unexpected EOF while reading dir
2 parents c0927a7 + d5c514b commit e103ece

File tree

8 files changed

+101
-60
lines changed

8 files changed

+101
-60
lines changed

fs/exfat/dir.c

Lines changed: 60 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@ static int exfat_extract_uni_name(struct exfat_dentry *ep,
2929

3030
}
3131

32-
static void exfat_get_uniname_from_ext_entry(struct super_block *sb,
32+
static int exfat_get_uniname_from_ext_entry(struct super_block *sb,
3333
struct exfat_chain *p_dir, int entry, unsigned short *uniname)
3434
{
35-
int i;
35+
int i, err;
3636
struct exfat_entry_set_cache es;
3737

38-
if (exfat_get_dentry_set(&es, sb, p_dir, entry, ES_ALL_ENTRIES))
39-
return;
38+
err = exfat_get_dentry_set(&es, sb, p_dir, entry, ES_ALL_ENTRIES);
39+
if (err)
40+
return err;
4041

4142
/*
4243
* First entry : file entry
@@ -56,12 +57,13 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb,
5657
}
5758

5859
exfat_put_dentry_set(&es, false);
60+
return 0;
5961
}
6062

6163
/* read a directory entry from the opened directory */
6264
static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_entry *dir_entry)
6365
{
64-
int i, dentries_per_clu, num_ext;
66+
int i, dentries_per_clu, num_ext, err;
6567
unsigned int type, clu_offset, max_dentries;
6668
struct exfat_chain dir, clu;
6769
struct exfat_uni_name uni_name;
@@ -100,7 +102,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
100102
clu.dir = ei->hint_bmap.clu;
101103
}
102104

103-
while (clu_offset > 0) {
105+
while (clu_offset > 0 && clu.dir != EXFAT_EOF_CLUSTER) {
104106
if (exfat_get_next_cluster(sb, &(clu.dir)))
105107
return -EIO;
106108

@@ -146,8 +148,12 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
146148
0);
147149

148150
*uni_name.name = 0x0;
149-
exfat_get_uniname_from_ext_entry(sb, &clu, i,
151+
err = exfat_get_uniname_from_ext_entry(sb, &clu, i,
150152
uni_name.name);
153+
if (err) {
154+
brelse(bh);
155+
continue;
156+
}
151157
exfat_utf16_to_nls(sb, &uni_name,
152158
dir_entry->namebuf.lfn,
153159
dir_entry->namebuf.lfnbuf_len);
@@ -234,10 +240,7 @@ static int exfat_iterate(struct file *file, struct dir_context *ctx)
234240
fake_offset = 1;
235241
}
236242

237-
if (cpos & (DENTRY_SIZE - 1)) {
238-
err = -ENOENT;
239-
goto unlock;
240-
}
243+
cpos = round_up(cpos, DENTRY_SIZE);
241244

242245
/* name buffer should be allocated before use */
243246
err = exfat_alloc_namebuf(nb);
@@ -378,6 +381,12 @@ unsigned int exfat_get_entry_type(struct exfat_dentry *ep)
378381
return TYPE_ACL;
379382
return TYPE_CRITICAL_SEC;
380383
}
384+
385+
if (ep->type == EXFAT_VENDOR_EXT)
386+
return TYPE_VENDOR_EXT;
387+
if (ep->type == EXFAT_VENDOR_ALLOC)
388+
return TYPE_VENDOR_ALLOC;
389+
381390
return TYPE_BENIGN_SEC;
382391
}
383392

@@ -521,6 +530,25 @@ int exfat_update_dir_chksum(struct inode *inode, struct exfat_chain *p_dir,
521530
return ret;
522531
}
523532

533+
static void exfat_free_benign_secondary_clusters(struct inode *inode,
534+
struct exfat_dentry *ep)
535+
{
536+
struct super_block *sb = inode->i_sb;
537+
struct exfat_chain dir;
538+
unsigned int start_clu =
539+
le32_to_cpu(ep->dentry.generic_secondary.start_clu);
540+
u64 size = le64_to_cpu(ep->dentry.generic_secondary.size);
541+
unsigned char flags = ep->dentry.generic_secondary.flags;
542+
543+
if (!(flags & ALLOC_POSSIBLE) || !start_clu || !size)
544+
return;
545+
546+
exfat_chain_set(&dir, start_clu,
547+
EXFAT_B_TO_CLU_ROUND_UP(size, EXFAT_SB(sb)),
548+
flags);
549+
exfat_free_cluster(inode, &dir);
550+
}
551+
524552
int exfat_init_ext_entry(struct inode *inode, struct exfat_chain *p_dir,
525553
int entry, int num_entries, struct exfat_uni_name *p_uniname)
526554
{
@@ -553,6 +581,9 @@ int exfat_init_ext_entry(struct inode *inode, struct exfat_chain *p_dir,
553581
if (!ep)
554582
return -EIO;
555583

584+
if (exfat_get_entry_type(ep) & TYPE_BENIGN_SEC)
585+
exfat_free_benign_secondary_clusters(inode, ep);
586+
556587
exfat_init_name_entry(ep, uniname);
557588
exfat_update_bh(bh, sync);
558589
brelse(bh);
@@ -576,6 +607,9 @@ int exfat_remove_entries(struct inode *inode, struct exfat_chain *p_dir,
576607
if (!ep)
577608
return -EIO;
578609

610+
if (exfat_get_entry_type(ep) & TYPE_BENIGN_SEC)
611+
exfat_free_benign_secondary_clusters(inode, ep);
612+
579613
exfat_set_entry_type(ep, TYPE_DELETED);
580614
exfat_update_bh(bh, IS_DIRSYNC(inode));
581615
brelse(bh);
@@ -744,6 +778,7 @@ enum exfat_validate_dentry_mode {
744778
ES_MODE_GET_STRM_ENTRY,
745779
ES_MODE_GET_NAME_ENTRY,
746780
ES_MODE_GET_CRITICAL_SEC_ENTRY,
781+
ES_MODE_GET_BENIGN_SEC_ENTRY,
747782
};
748783

749784
static bool exfat_validate_entry(unsigned int type,
@@ -757,36 +792,33 @@ static bool exfat_validate_entry(unsigned int type,
757792
if (type != TYPE_FILE && type != TYPE_DIR)
758793
return false;
759794
*mode = ES_MODE_GET_FILE_ENTRY;
760-
return true;
795+
break;
761796
case ES_MODE_GET_FILE_ENTRY:
762797
if (type != TYPE_STREAM)
763798
return false;
764799
*mode = ES_MODE_GET_STRM_ENTRY;
765-
return true;
800+
break;
766801
case ES_MODE_GET_STRM_ENTRY:
767802
if (type != TYPE_EXTEND)
768803
return false;
769804
*mode = ES_MODE_GET_NAME_ENTRY;
770-
return true;
805+
break;
771806
case ES_MODE_GET_NAME_ENTRY:
772-
if (type == TYPE_STREAM)
773-
return false;
774-
if (type != TYPE_EXTEND) {
775-
if (!(type & TYPE_CRITICAL_SEC))
776-
return false;
777-
*mode = ES_MODE_GET_CRITICAL_SEC_ENTRY;
778-
}
779-
return true;
780-
case ES_MODE_GET_CRITICAL_SEC_ENTRY:
781-
if (type == TYPE_EXTEND || type == TYPE_STREAM)
807+
if (type & TYPE_BENIGN_SEC)
808+
*mode = ES_MODE_GET_BENIGN_SEC_ENTRY;
809+
else if (type != TYPE_EXTEND)
782810
return false;
783-
if ((type & TYPE_CRITICAL_SEC) != TYPE_CRITICAL_SEC)
811+
break;
812+
case ES_MODE_GET_BENIGN_SEC_ENTRY:
813+
/* Assume unreconized benign secondary entry */
814+
if (!(type & TYPE_BENIGN_SEC))
784815
return false;
785-
return true;
816+
break;
786817
default:
787-
WARN_ON_ONCE(1);
788818
return false;
789819
}
820+
821+
return true;
790822
}
791823

792824
struct exfat_dentry *exfat_get_dentry_cached(
@@ -1167,10 +1199,8 @@ int exfat_count_ext_entries(struct super_block *sb, struct exfat_chain *p_dir,
11671199

11681200
type = exfat_get_entry_type(ext_ep);
11691201
brelse(bh);
1170-
if (type == TYPE_EXTEND || type == TYPE_STREAM)
1202+
if (type & TYPE_CRITICAL_SEC || type & TYPE_BENIGN_SEC)
11711203
count++;
1172-
else
1173-
break;
11741204
}
11751205
return count;
11761206
}

fs/exfat/exfat_fs.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ enum {
5050
#define ES_IDX_LAST_FILENAME(name_len) \
5151
(ES_IDX_FIRST_FILENAME + EXFAT_FILENAME_ENTRY_NUM(name_len) - 1)
5252

53-
#define DIR_DELETED 0xFFFF0321
53+
#define DIR_DELETED 0xFFFFFFF7
5454

5555
/* type values */
5656
#define TYPE_UNUSED 0x0000
@@ -71,6 +71,8 @@ enum {
7171
#define TYPE_PADDING 0x0402
7272
#define TYPE_ACLTAB 0x0403
7373
#define TYPE_BENIGN_SEC 0x0800
74+
#define TYPE_VENDOR_EXT 0x0801
75+
#define TYPE_VENDOR_ALLOC 0x0802
7476

7577
#define MAX_CHARSET_SIZE 6 /* max size of multi-byte character */
7678
#define MAX_NAME_LENGTH 255 /* max len of file name excluding NULL */

fs/exfat/exfat_raw.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
((sbi)->num_clusters - EXFAT_RESERVED_CLUSTERS)
2828

2929
/* AllocationPossible and NoFatChain field in GeneralSecondaryFlags Field */
30+
#define ALLOC_POSSIBLE 0x01
3031
#define ALLOC_FAT_CHAIN 0x01
3132
#define ALLOC_NO_FAT_CHAIN 0x03
3233

@@ -50,6 +51,8 @@
5051
#define EXFAT_STREAM 0xC0 /* stream entry */
5152
#define EXFAT_NAME 0xC1 /* file name entry */
5253
#define EXFAT_ACL 0xC2 /* stream entry */
54+
#define EXFAT_VENDOR_EXT 0xE0 /* vendor extension entry */
55+
#define EXFAT_VENDOR_ALLOC 0xE1 /* vendor allocation entry */
5356

5457
#define IS_EXFAT_CRITICAL_PRI(x) (x < 0xA0)
5558
#define IS_EXFAT_BENIGN_PRI(x) (x < 0xC0)
@@ -155,6 +158,24 @@ struct exfat_dentry {
155158
__le32 start_clu;
156159
__le64 size;
157160
} __packed upcase; /* up-case table directory entry */
161+
struct {
162+
__u8 flags;
163+
__u8 vendor_guid[16];
164+
__u8 vendor_defined[14];
165+
} __packed vendor_ext; /* vendor extension directory entry */
166+
struct {
167+
__u8 flags;
168+
__u8 vendor_guid[16];
169+
__u8 vendor_defined[2];
170+
__le32 start_clu;
171+
__le64 size;
172+
} __packed vendor_alloc; /* vendor allocation directory entry */
173+
struct {
174+
__u8 flags;
175+
__u8 custom_defined[18];
176+
__le32 start_clu;
177+
__le64 size;
178+
} __packed generic_secondary; /* generic secondary directory entry */
158179
} __packed dentry;
159180
} __packed;
160181

fs/exfat/fatent.c

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
307307
struct exfat_chain *p_chain, bool sync_bmap)
308308
{
309309
int ret = -ENOSPC;
310-
unsigned int num_clusters = 0, total_cnt;
310+
unsigned int total_cnt;
311311
unsigned int hint_clu, new_clu, last_clu = EXFAT_EOF_CLUSTER;
312312
struct super_block *sb = inode->i_sb;
313313
struct exfat_sb_info *sbi = EXFAT_SB(sb);
@@ -344,17 +344,11 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
344344

345345
/* check cluster validation */
346346
if (!is_valid_cluster(sbi, hint_clu)) {
347-
exfat_err(sb, "hint_cluster is invalid (%u)",
348-
hint_clu);
347+
if (hint_clu != sbi->num_clusters)
348+
exfat_err(sb, "hint_cluster is invalid (%u), rewind to the first cluster",
349+
hint_clu);
349350
hint_clu = EXFAT_FIRST_CLUSTER;
350-
if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
351-
if (exfat_chain_cont_cluster(sb, p_chain->dir,
352-
num_clusters)) {
353-
ret = -EIO;
354-
goto unlock;
355-
}
356-
p_chain->flags = ALLOC_FAT_CHAIN;
357-
}
351+
p_chain->flags = ALLOC_FAT_CHAIN;
358352
}
359353

360354
p_chain->dir = EXFAT_EOF_CLUSTER;
@@ -364,7 +358,7 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
364358
if (new_clu != hint_clu &&
365359
p_chain->flags == ALLOC_NO_FAT_CHAIN) {
366360
if (exfat_chain_cont_cluster(sb, p_chain->dir,
367-
num_clusters)) {
361+
p_chain->size)) {
368362
ret = -EIO;
369363
goto free_cluster;
370364
}
@@ -377,8 +371,6 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
377371
goto free_cluster;
378372
}
379373

380-
num_clusters++;
381-
382374
/* update FAT table */
383375
if (p_chain->flags == ALLOC_FAT_CHAIN) {
384376
if (exfat_ent_set(sb, new_clu, EXFAT_EOF_CLUSTER)) {
@@ -395,13 +387,14 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
395387
goto free_cluster;
396388
}
397389
}
390+
p_chain->size++;
391+
398392
last_clu = new_clu;
399393

400-
if (--num_alloc == 0) {
394+
if (p_chain->size == num_alloc) {
401395
sbi->clu_srch_ptr = hint_clu;
402-
sbi->used_clusters += num_clusters;
396+
sbi->used_clusters += num_alloc;
403397

404-
p_chain->size += num_clusters;
405398
mutex_unlock(&sbi->bitmap_lock);
406399
return 0;
407400
}
@@ -412,7 +405,7 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
412405

413406
if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
414407
if (exfat_chain_cont_cluster(sb, p_chain->dir,
415-
num_clusters)) {
408+
p_chain->size)) {
416409
ret = -EIO;
417410
goto free_cluster;
418411
}
@@ -421,8 +414,7 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
421414
}
422415
}
423416
free_cluster:
424-
if (num_clusters)
425-
__exfat_free_cluster(inode, p_chain);
417+
__exfat_free_cluster(inode, p_chain);
426418
unlock:
427419
mutex_unlock(&sbi->bitmap_lock);
428420
return ret;

fs/exfat/file.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,7 @@ void exfat_truncate(struct inode *inode)
209209
if (err)
210210
goto write_size;
211211

212-
inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >>
213-
inode->i_blkbits;
212+
inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9;
214213
write_size:
215214
aligned_size = i_size_read(inode);
216215
if (aligned_size & (blocksize - 1)) {

fs/exfat/inode.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,7 @@ static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset,
220220
num_clusters += num_to_be_allocated;
221221
*clu = new_clu.dir;
222222

223-
inode->i_blocks +=
224-
num_to_be_allocated << sbi->sect_per_clus_bits;
223+
inode->i_blocks += EXFAT_CLU_TO_B(num_to_be_allocated, sbi) >> 9;
225224

226225
/*
227226
* Move *clu pointer along FAT chains (hole care) because the
@@ -576,8 +575,7 @@ static int exfat_fill_inode(struct inode *inode, struct exfat_dir_entry *info)
576575

577576
exfat_save_attr(inode, info->attr);
578577

579-
inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >>
580-
inode->i_blkbits;
578+
inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9;
581579
inode->i_mtime = info->mtime;
582580
inode->i_ctime = info->mtime;
583581
ei->i_crtime = info->crtime;

fs/exfat/namei.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ static int exfat_find_empty_entry(struct inode *inode,
396396
ei->i_size_ondisk += sbi->cluster_size;
397397
ei->i_size_aligned += sbi->cluster_size;
398398
ei->flags = p_dir->flags;
399-
inode->i_blocks += 1 << sbi->sect_per_clus_bits;
399+
inode->i_blocks += sbi->cluster_size >> 9;
400400
}
401401

402402
return dentry;

fs/exfat/super.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,7 @@ static int exfat_read_root(struct inode *inode)
373373
inode->i_op = &exfat_dir_inode_operations;
374374
inode->i_fop = &exfat_dir_operations;
375375

376-
inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >>
377-
inode->i_blkbits;
376+
inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9;
378377
ei->i_pos = ((loff_t)sbi->root_dir << 32) | 0xffffffff;
379378
ei->i_size_aligned = i_size_read(inode);
380379
ei->i_size_ondisk = i_size_read(inode);

0 commit comments

Comments
 (0)