Skip to content

Commit f72fb74

Browse files
committed
Merge tag 'exfat-for-5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat
Pull exfat updates from Namjae Jeon: - fix the error code of rename syscall - cleanup and suppress the superfluous error messages - remove duplicate directory entry update - add exfat git tree in MAINTAINERS * tag 'exfat-for-5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat: MAINTAINERS: Add Namjae's exfat git tree exfat: Drop superfluous new line for error messages exfat: Downgrade ENAMETOOLONG error message to debug messages exfat: Expand exfat_err() and co directly to pr_*() macro exfat: Define NLS_NAME_* as bit flags explicitly exfat: Return ENAMETOOLONG consistently for oversized paths exfat: remove duplicate write inode for extending dir/file exfat: remove duplicate write inode for truncating file exfat: reuse __exfat_write_inode() to update directory entry
2 parents e2ebff9 + df13a34 commit f72fb74

9 files changed

Lines changed: 54 additions & 138 deletions

File tree

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7690,6 +7690,7 @@ M: Namjae Jeon <linkinjeon@kernel.org>
76907690
M: Sungjong Seo <sj1557.seo@samsung.com>
76917691
L: linux-fsdevel@vger.kernel.org
76927692
S: Maintained
7693+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat.git
76937694
F: fs/exfat/
76947695

76957696
EXT2 FILE SYSTEM

fs/exfat/exfat_fs.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ enum exfat_error_mode {
2727
* exfat nls lossy flag
2828
*/
2929
enum {
30-
NLS_NAME_NO_LOSSY, /* no lossy */
31-
NLS_NAME_LOSSY, /* just detected incorrect filename(s) */
32-
NLS_NAME_OVERLEN, /* the length is over than its limit */
30+
NLS_NAME_NO_LOSSY = 0, /* no lossy */
31+
NLS_NAME_LOSSY = 1 << 0, /* just detected incorrect filename(s) */
32+
NLS_NAME_OVERLEN = 1 << 1, /* the length is over than its limit */
3333
};
3434

3535
#define EXFAT_HASH_BITS 8
@@ -483,6 +483,7 @@ struct inode *exfat_build_inode(struct super_block *sb,
483483
void exfat_hash_inode(struct inode *inode, loff_t i_pos);
484484
void exfat_unhash_inode(struct inode *inode);
485485
struct inode *exfat_iget(struct super_block *sb, loff_t i_pos);
486+
int __exfat_write_inode(struct inode *inode, int sync);
486487
int exfat_write_inode(struct inode *inode, struct writeback_control *wbc);
487488
void exfat_evict_inode(struct inode *inode);
488489
int exfat_block_truncate_page(struct inode *inode, loff_t from);
@@ -508,14 +509,16 @@ void __exfat_fs_error(struct super_block *sb, int report, const char *fmt, ...)
508509
#define exfat_fs_error_ratelimit(sb, fmt, args...) \
509510
__exfat_fs_error(sb, __ratelimit(&EXFAT_SB(sb)->ratelimit), \
510511
fmt, ## args)
511-
void exfat_msg(struct super_block *sb, const char *lv, const char *fmt, ...)
512-
__printf(3, 4) __cold;
512+
513+
/* expand to pr_*() with prefix */
513514
#define exfat_err(sb, fmt, ...) \
514-
exfat_msg(sb, KERN_ERR, fmt, ##__VA_ARGS__)
515+
pr_err("exFAT-fs (%s): " fmt "\n", (sb)->s_id, ##__VA_ARGS__)
515516
#define exfat_warn(sb, fmt, ...) \
516-
exfat_msg(sb, KERN_WARNING, fmt, ##__VA_ARGS__)
517+
pr_warn("exFAT-fs (%s): " fmt "\n", (sb)->s_id, ##__VA_ARGS__)
517518
#define exfat_info(sb, fmt, ...) \
518-
exfat_msg(sb, KERN_INFO, fmt, ##__VA_ARGS__)
519+
pr_info("exFAT-fs (%s): " fmt "\n", (sb)->s_id, ##__VA_ARGS__)
520+
#define exfat_debug(sb, fmt, ...) \
521+
pr_debug("exFAT-fs (%s): " fmt "\n", (sb)->s_id, ##__VA_ARGS__)
519522

520523
void exfat_get_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts,
521524
u8 tz, __le16 time, __le16 date, u8 time_cs);

fs/exfat/fatent.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
331331
/* find new cluster */
332332
if (hint_clu == EXFAT_EOF_CLUSTER) {
333333
if (sbi->clu_srch_ptr < EXFAT_FIRST_CLUSTER) {
334-
exfat_err(sb, "sbi->clu_srch_ptr is invalid (%u)\n",
334+
exfat_err(sb, "sbi->clu_srch_ptr is invalid (%u)",
335335
sbi->clu_srch_ptr);
336336
sbi->clu_srch_ptr = EXFAT_FIRST_CLUSTER;
337337
}

fs/exfat/file.c

Lines changed: 26 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ int __exfat_truncate(struct inode *inode, loff_t new_size)
101101
struct super_block *sb = inode->i_sb;
102102
struct exfat_sb_info *sbi = EXFAT_SB(sb);
103103
struct exfat_inode_info *ei = EXFAT_I(inode);
104-
int evict = (ei->dir.dir == DIR_DELETED) ? 1 : 0;
105104

106105
/* check if the given file ID is opened */
107106
if (ei->type != TYPE_FILE && ei->type != TYPE_DIR)
@@ -149,50 +148,19 @@ int __exfat_truncate(struct inode *inode, loff_t new_size)
149148
if (ei->type == TYPE_FILE)
150149
ei->attr |= ATTR_ARCHIVE;
151150

152-
/* update the directory entry */
153-
if (!evict) {
154-
struct timespec64 ts;
155-
struct exfat_dentry *ep, *ep2;
156-
struct exfat_entry_set_cache *es;
157-
int err;
158-
159-
es = exfat_get_dentry_set(sb, &(ei->dir), ei->entry,
160-
ES_ALL_ENTRIES);
161-
if (!es)
162-
return -EIO;
163-
ep = exfat_get_dentry_cached(es, 0);
164-
ep2 = exfat_get_dentry_cached(es, 1);
165-
166-
ts = current_time(inode);
167-
exfat_set_entry_time(sbi, &ts,
168-
&ep->dentry.file.modify_tz,
169-
&ep->dentry.file.modify_time,
170-
&ep->dentry.file.modify_date,
171-
&ep->dentry.file.modify_time_cs);
172-
ep->dentry.file.attr = cpu_to_le16(ei->attr);
173-
174-
/* File size should be zero if there is no cluster allocated */
175-
if (ei->start_clu == EXFAT_EOF_CLUSTER) {
176-
ep2->dentry.stream.valid_size = 0;
177-
ep2->dentry.stream.size = 0;
178-
} else {
179-
ep2->dentry.stream.valid_size = cpu_to_le64(new_size);
180-
ep2->dentry.stream.size = ep2->dentry.stream.valid_size;
181-
}
182-
183-
if (new_size == 0) {
184-
/* Any directory can not be truncated to zero */
185-
WARN_ON(ei->type != TYPE_FILE);
186-
187-
ep2->dentry.stream.flags = ALLOC_FAT_CHAIN;
188-
ep2->dentry.stream.start_clu = EXFAT_FREE_CLUSTER;
189-
}
190-
191-
exfat_update_dir_chksum_with_entry_set(es);
192-
err = exfat_free_dentry_set(es, inode_needs_sync(inode));
193-
if (err)
194-
return err;
195-
}
151+
/*
152+
* update the directory entry
153+
*
154+
* If the directory entry is updated by mark_inode_dirty(), the
155+
* directory entry will be written after a writeback cycle of
156+
* updating the bitmap/FAT, which may result in clusters being
157+
* freed but referenced by the directory entry in the event of a
158+
* sudden power failure.
159+
* __exfat_write_inode() is called for directory entry, bitmap
160+
* and FAT to be written in a same writeback.
161+
*/
162+
if (__exfat_write_inode(inode, inode_needs_sync(inode)))
163+
return -EIO;
196164

197165
/* cut off from the FAT chain */
198166
if (ei->flags == ALLOC_FAT_CHAIN && last_clu != EXFAT_FREE_CLUSTER &&
@@ -243,12 +211,6 @@ void exfat_truncate(struct inode *inode, loff_t size)
243211
if (err)
244212
goto write_size;
245213

246-
inode->i_ctime = inode->i_mtime = current_time(inode);
247-
if (IS_DIRSYNC(inode))
248-
exfat_sync_inode(inode);
249-
else
250-
mark_inode_dirty(inode);
251-
252214
inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >>
253215
inode->i_blkbits;
254216
write_size:
@@ -330,20 +292,28 @@ int exfat_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
330292
attr->ia_valid &= ~ATTR_MODE;
331293
}
332294

295+
if (attr->ia_valid & ATTR_SIZE)
296+
inode->i_mtime = inode->i_ctime = current_time(inode);
297+
298+
setattr_copy(&init_user_ns, inode, attr);
299+
exfat_truncate_atime(&inode->i_atime);
300+
333301
if (attr->ia_valid & ATTR_SIZE) {
334302
error = exfat_block_truncate_page(inode, attr->ia_size);
335303
if (error)
336304
goto out;
337305

338306
down_write(&EXFAT_I(inode)->truncate_lock);
339307
truncate_setsize(inode, attr->ia_size);
308+
309+
/*
310+
* __exfat_write_inode() is called from exfat_truncate(), inode
311+
* is already written by it, so mark_inode_dirty() is unneeded.
312+
*/
340313
exfat_truncate(inode, attr->ia_size);
341314
up_write(&EXFAT_I(inode)->truncate_lock);
342-
}
343-
344-
setattr_copy(&init_user_ns, inode, attr);
345-
exfat_truncate_atime(&inode->i_atime);
346-
mark_inode_dirty(inode);
315+
} else
316+
mark_inode_dirty(inode);
347317

348318
out:
349319
return error;

fs/exfat/inode.c

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include "exfat_raw.h"
1818
#include "exfat_fs.h"
1919

20-
static int __exfat_write_inode(struct inode *inode, int sync)
20+
int __exfat_write_inode(struct inode *inode, int sync)
2121
{
2222
unsigned long long on_disk_size;
2323
struct exfat_dentry *ep, *ep2;
@@ -75,6 +75,13 @@ static int __exfat_write_inode(struct inode *inode, int sync)
7575

7676
ep2->dentry.stream.valid_size = cpu_to_le64(on_disk_size);
7777
ep2->dentry.stream.size = ep2->dentry.stream.valid_size;
78+
if (on_disk_size) {
79+
ep2->dentry.stream.flags = ei->flags;
80+
ep2->dentry.stream.start_clu = cpu_to_le32(ei->start_clu);
81+
} else {
82+
ep2->dentry.stream.flags = ALLOC_FAT_CHAIN;
83+
ep2->dentry.stream.start_clu = EXFAT_FREE_CLUSTER;
84+
}
7885

7986
exfat_update_dir_chksum_with_entry_set(es);
8087
return exfat_free_dentry_set(es, sync);
@@ -105,7 +112,7 @@ void exfat_sync_inode(struct inode *inode)
105112
static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset,
106113
unsigned int *clu, int create)
107114
{
108-
int ret, modified = false;
115+
int ret;
109116
unsigned int last_clu;
110117
struct exfat_chain new_clu;
111118
struct super_block *sb = inode->i_sb;
@@ -196,7 +203,6 @@ static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset,
196203
if (new_clu.flags == ALLOC_FAT_CHAIN)
197204
ei->flags = ALLOC_FAT_CHAIN;
198205
ei->start_clu = new_clu.dir;
199-
modified = true;
200206
} else {
201207
if (new_clu.flags != ei->flags) {
202208
/* no-fat-chain bit is disabled,
@@ -206,7 +212,6 @@ static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset,
206212
exfat_chain_cont_cluster(sb, ei->start_clu,
207213
num_clusters);
208214
ei->flags = ALLOC_FAT_CHAIN;
209-
modified = true;
210215
}
211216
if (new_clu.flags == ALLOC_FAT_CHAIN)
212217
if (exfat_ent_set(sb, last_clu, new_clu.dir))
@@ -216,33 +221,6 @@ static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset,
216221
num_clusters += num_to_be_allocated;
217222
*clu = new_clu.dir;
218223

219-
if (ei->dir.dir != DIR_DELETED && modified) {
220-
struct exfat_dentry *ep;
221-
struct exfat_entry_set_cache *es;
222-
int err;
223-
224-
es = exfat_get_dentry_set(sb, &(ei->dir), ei->entry,
225-
ES_ALL_ENTRIES);
226-
if (!es)
227-
return -EIO;
228-
/* get stream entry */
229-
ep = exfat_get_dentry_cached(es, 1);
230-
231-
/* update directory entry */
232-
ep->dentry.stream.flags = ei->flags;
233-
ep->dentry.stream.start_clu =
234-
cpu_to_le32(ei->start_clu);
235-
ep->dentry.stream.valid_size =
236-
cpu_to_le64(i_size_read(inode));
237-
ep->dentry.stream.size =
238-
ep->dentry.stream.valid_size;
239-
240-
exfat_update_dir_chksum_with_entry_set(es);
241-
err = exfat_free_dentry_set(es, inode_needs_sync(inode));
242-
if (err)
243-
return err;
244-
} /* end of if != DIR_DELETED */
245-
246224
inode->i_blocks +=
247225
num_to_be_allocated << sbi->sect_per_clus_bits;
248226

@@ -384,6 +362,7 @@ static void exfat_write_failed(struct address_space *mapping, loff_t to)
384362

385363
if (to > i_size_read(inode)) {
386364
truncate_pagecache(inode, i_size_read(inode));
365+
inode->i_mtime = inode->i_ctime = current_time(inode);
387366
exfat_truncate(inode, EXFAT_I(inode)->i_size_aligned);
388367
}
389368
}

fs/exfat/misc.c

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,23 +46,6 @@ void __exfat_fs_error(struct super_block *sb, int report, const char *fmt, ...)
4646
}
4747
}
4848

49-
/*
50-
* exfat_msg() - print preformated EXFAT specific messages.
51-
* All logs except what uses exfat_fs_error() should be written by exfat_msg()
52-
*/
53-
void exfat_msg(struct super_block *sb, const char *level, const char *fmt, ...)
54-
{
55-
struct va_format vaf;
56-
va_list args;
57-
58-
va_start(args, fmt);
59-
vaf.fmt = fmt;
60-
vaf.va = &args;
61-
/* level means KERN_ pacility level */
62-
printk("%sexFAT-fs (%s): %pV\n", level, sb->s_id, &vaf);
63-
va_end(args);
64-
}
65-
6649
#define SECS_PER_MIN (60)
6750
#define TIMEZONE_SEC(x) ((x) * 15 * SECS_PER_MIN)
6851

fs/exfat/namei.c

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,6 @@ static int exfat_find_empty_entry(struct inode *inode,
318318
unsigned int ret, last_clu;
319319
loff_t size = 0;
320320
struct exfat_chain clu;
321-
struct exfat_dentry *ep = NULL;
322321
struct super_block *sb = inode->i_sb;
323322
struct exfat_sb_info *sbi = EXFAT_SB(sb);
324323
struct exfat_inode_info *ei = EXFAT_I(inode);
@@ -383,25 +382,6 @@ static int exfat_find_empty_entry(struct inode *inode,
383382
p_dir->size++;
384383
size = EXFAT_CLU_TO_B(p_dir->size, sbi);
385384

386-
/* update the directory entry */
387-
if (p_dir->dir != sbi->root_dir) {
388-
struct buffer_head *bh;
389-
390-
ep = exfat_get_dentry(sb,
391-
&(ei->dir), ei->entry + 1, &bh);
392-
if (!ep)
393-
return -EIO;
394-
395-
ep->dentry.stream.valid_size = cpu_to_le64(size);
396-
ep->dentry.stream.size = ep->dentry.stream.valid_size;
397-
ep->dentry.stream.flags = p_dir->flags;
398-
exfat_update_bh(bh, IS_DIRSYNC(inode));
399-
brelse(bh);
400-
if (exfat_update_dir_chksum(inode, &(ei->dir),
401-
ei->entry))
402-
return -EIO;
403-
}
404-
405385
/* directory inode should be updated in here */
406386
i_size_write(inode, size);
407387
ei->i_size_ondisk += sbi->cluster_size;
@@ -462,7 +442,7 @@ static int __exfat_resolve_path(struct inode *inode, const unsigned char *path,
462442
return namelen; /* return error value */
463443

464444
if ((lossy && !lookup) || !namelen)
465-
return -EINVAL;
445+
return (lossy & NLS_NAME_OVERLEN) ? -ENAMETOOLONG : -EINVAL;
466446

467447
exfat_chain_set(p_dir, ei->start_clu,
468448
EXFAT_B_TO_CLU(i_size_read(inode), sbi), ei->flags);

fs/exfat/nls.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ static int exfat_utf8_to_utf16(struct super_block *sb,
509509
}
510510

511511
if (unilen > MAX_NAME_LENGTH) {
512-
exfat_err(sb, "failed to %s (estr:ENAMETOOLONG) nls len : %d, unilen : %d > %d",
512+
exfat_debug(sb, "failed to %s (estr:ENAMETOOLONG) nls len : %d, unilen : %d > %d",
513513
__func__, len, unilen, MAX_NAME_LENGTH);
514514
return -ENAMETOOLONG;
515515
}
@@ -671,7 +671,7 @@ static int exfat_load_upcase_table(struct super_block *sb,
671671

672672
bh = sb_bread(sb, sector);
673673
if (!bh) {
674-
exfat_err(sb, "failed to read sector(0x%llx)\n",
674+
exfat_err(sb, "failed to read sector(0x%llx)",
675675
(unsigned long long)sector);
676676
ret = -EIO;
677677
goto free_table;

fs/exfat/super.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ static int exfat_read_boot_sector(struct super_block *sb)
464464
*/
465465
if (p_boot->sect_size_bits < EXFAT_MIN_SECT_SIZE_BITS ||
466466
p_boot->sect_size_bits > EXFAT_MAX_SECT_SIZE_BITS) {
467-
exfat_err(sb, "bogus sector size bits : %u\n",
467+
exfat_err(sb, "bogus sector size bits : %u",
468468
p_boot->sect_size_bits);
469469
return -EINVAL;
470470
}
@@ -473,7 +473,7 @@ static int exfat_read_boot_sector(struct super_block *sb)
473473
* sect_per_clus_bits could be at least 0 and at most 25 - sect_size_bits.
474474
*/
475475
if (p_boot->sect_per_clus_bits > EXFAT_MAX_SECT_PER_CLUS_BITS(p_boot)) {
476-
exfat_err(sb, "bogus sectors bits per cluster : %u\n",
476+
exfat_err(sb, "bogus sectors bits per cluster : %u",
477477
p_boot->sect_per_clus_bits);
478478
return -EINVAL;
479479
}

0 commit comments

Comments
 (0)