summaryrefslogtreecommitdiff
path: root/fs/f2fs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/f2fs/dir.c')
-rw-r--r--fs/f2fs/dir.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index f70092e231f0..fd0e2cd31a81 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -11,6 +11,7 @@
#include <linux/filelock.h>
#include <linux/sched/signal.h>
#include <linux/unicode.h>
+#include <linux/fserror.h>
#include "f2fs.h"
#include "node.h"
#include "acl.h"
@@ -249,6 +250,11 @@ struct f2fs_dir_entry *f2fs_find_target_dentry(const struct f2fs_dentry_ptr *d,
continue;
}
+ if (unlikely(le16_to_cpu(de->name_len) > F2FS_NAME_LEN ||
+ bit_pos + GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)) >
+ d->max))
+ return ERR_PTR(-EFSCORRUPTED);
+
if (!use_hash || de->hash_code == fname->hash) {
res = f2fs_match_name(d->inode, fname,
d->filename[bit_pos],
@@ -314,6 +320,7 @@ start_find_bucket:
de = find_in_block(dir, dentry_folio, fname, &max_slots, use_hash);
if (IS_ERR(de)) {
+ f2fs_folio_put(dentry_folio, false);
*res_folio = ERR_CAST(de);
de = NULL;
break;
@@ -368,7 +375,7 @@ start_find_entry:
max_depth = F2FS_I(dir)->i_current_depth;
if (unlikely(max_depth > MAX_DIR_HASH_DEPTH)) {
- f2fs_warn(F2FS_I_SB(dir), "Corrupted max_depth of %lu: %u",
+ f2fs_warn(F2FS_I_SB(dir), "Corrupted max_depth of %llu: %u",
dir->i_ino, max_depth);
max_depth = MAX_DIR_HASH_DEPTH;
f2fs_i_depth_write(dir, max_depth);
@@ -454,7 +461,7 @@ void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de,
folio_mark_dirty(folio);
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
- f2fs_mark_inode_dirty_sync(dir, false);
+ f2fs_mark_inode_dirty_sync(dir, true);
f2fs_folio_put(folio, true);
}
@@ -609,7 +616,7 @@ void f2fs_update_parent_metadata(struct inode *dir, struct inode *inode,
clear_inode_flag(inode, FI_NEW_INODE);
}
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
- f2fs_mark_inode_dirty_sync(dir, false);
+ f2fs_mark_inode_dirty_sync(dir, true);
if (F2FS_I(dir)->i_current_depth != current_depth)
f2fs_i_depth_write(dir, current_depth);
@@ -921,7 +928,7 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct folio *folio,
f2fs_folio_put(folio, true);
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
- f2fs_mark_inode_dirty_sync(dir, false);
+ f2fs_mark_inode_dirty_sync(dir, true);
if (inode)
f2fs_drop_nlink(dir, inode);
@@ -1020,6 +1027,7 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
set_sbi_flag(sbi, SBI_NEED_FSCK);
err = -EFSCORRUPTED;
f2fs_handle_error(sbi, ERROR_CORRUPTED_DIRENT);
+ fserror_report_file_metadata(d->inode, err, GFP_NOFS);
goto out;
}