Commit d54d35c5 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'f2fs-for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs

Pull f2fs updates from Jaegeuk Kim:
 "In this round, we've mainly focused on discard, aka unmap, control
  along with fstrim for Android-specific usage model. In addition, we've
  fixed writepage flow which returned EAGAIN previously resulting in EIO
  of fsync(2) due to mapping's error state. In order to avoid old MM bug
  [1], we decided not to use __GFP_ZERO for the mapping for node and
  meta page caches. As always, we've cleaned up many places for future
  fsverity and symbol conflicts.

  Enhancements:
   - do discard/fstrim in lower priority considering fs utilization
   - split large discard commands into smaller ones for better responsiveness
   - add more sanity checks to address syzbot reports
   - add a mount option, fsync_mode=nobarrier, which can reduce # of cache flushes
   - clean up symbol namespace with modified function names
   - be strict on block allocation and IO control in corner cases

  Bug fixes:
   - don't use __GFP_ZERO for mappings
   - fix error reports in writepage to avoid fsync() failure
   - avoid selinux denial on CAP_RESOURCE on resgid/resuid
   - fix some subtle race conditions in GC/atomic writes/shutdown
   - fix overflow bugs in sanity_check_raw_super
   - fix missing bits on get_flags

  Clean-ups:
   - prepare the generic flow for future fsverity integration
   - fix some broken coding standard"

[1] https://lkml.org/lkml/2018/4/8/661

* tag 'f2fs-for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (79 commits)
  f2fs: fix to clear FI_VOLATILE_FILE correctly
  f2fs: let sync node IO interrupt async one
  f2fs: don't change wbc->sync_mode
  f2fs: fix to update mtime correctly
  fs: f2fs: insert space around that ':' and ', '
  fs: f2fs: add missing blank lines after declarations
  fs: f2fs: changed variable type of offset "unsigned" to "loff_t"
  f2fs: clean up symbol namespace
  f2fs: make set_de_type() static
  f2fs: make __f2fs_write_data_pages() static
  f2fs: fix to avoid accessing cross the boundary
  f2fs: fix to let caller retry allocating block address
  disable loading f2fs module on PAGE_SIZE > 4KB
  f2fs: fix error path of move_data_page
  f2fs: don't drop dentry pages after fs shutdown
  f2fs: fix to avoid race during access gc_thread pointer
  f2fs: clean up with clear_radix_tree_dirty_tag
  f2fs: fix to don't trigger writeback during recovery
  f2fs: clear discard_wake earlier
  f2fs: let discard thread wait a little longer if dev is busy
  ...
parents a2225d93 dfa74280
...@@ -101,6 +101,7 @@ Date: February 2015 ...@@ -101,6 +101,7 @@ Date: February 2015
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org> Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
Description: Description:
Controls the trimming rate in batch mode. Controls the trimming rate in batch mode.
<deprecated>
What: /sys/fs/f2fs/<disk>/cp_interval What: /sys/fs/f2fs/<disk>/cp_interval
Date: October 2015 Date: October 2015
...@@ -140,7 +141,7 @@ Contact: "Shuoran Liu" <liushuoran@huawei.com> ...@@ -140,7 +141,7 @@ Contact: "Shuoran Liu" <liushuoran@huawei.com>
Description: Description:
Shows total written kbytes issued to disk. Shows total written kbytes issued to disk.
What: /sys/fs/f2fs/<disk>/feature What: /sys/fs/f2fs/<disk>/features
Date: July 2017 Date: July 2017
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org> Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
Description: Description:
......
...@@ -182,13 +182,15 @@ whint_mode=%s Control which write hints are passed down to block ...@@ -182,13 +182,15 @@ whint_mode=%s Control which write hints are passed down to block
passes down hints with its policy. passes down hints with its policy.
alloc_mode=%s Adjust block allocation policy, which supports "reuse" alloc_mode=%s Adjust block allocation policy, which supports "reuse"
and "default". and "default".
fsync_mode=%s Control the policy of fsync. Currently supports "posix" fsync_mode=%s Control the policy of fsync. Currently supports "posix",
and "strict". In "posix" mode, which is default, fsync "strict", and "nobarrier". In "posix" mode, which is
will follow POSIX semantics and does a light operation default, fsync will follow POSIX semantics and does a
to improve the filesystem performance. In "strict" mode, light operation to improve the filesystem performance.
fsync will be heavy and behaves in line with xfs, ext4 In "strict" mode, fsync will be heavy and behaves in line
and btrfs, where xfstest generic/342 will pass, but the with xfs, ext4 and btrfs, where xfstest generic/342 will
performance will regress. pass, but the performance will regress. "nobarrier" is
based on "posix", but doesn't issue flush command for
non-atomic files likewise "nobarrier" mount option.
test_dummy_encryption Enable dummy encryption, which provides a fake fscrypt test_dummy_encryption Enable dummy encryption, which provides a fake fscrypt
context. The fake fscrypt context is used by xfstests. context. The fake fscrypt context is used by xfstests.
......
...@@ -26,15 +26,8 @@ ...@@ -26,15 +26,8 @@
#include <linux/namei.h> #include <linux/namei.h>
#include "fscrypt_private.h" #include "fscrypt_private.h"
/* static void __fscrypt_decrypt_bio(struct bio *bio, bool done)
* Call fscrypt_decrypt_page on every single page, reusing the encryption
* context.
*/
static void completion_pages(struct work_struct *work)
{ {
struct fscrypt_ctx *ctx =
container_of(work, struct fscrypt_ctx, r.work);
struct bio *bio = ctx->r.bio;
struct bio_vec *bv; struct bio_vec *bv;
int i; int i;
...@@ -46,22 +39,38 @@ static void completion_pages(struct work_struct *work) ...@@ -46,22 +39,38 @@ static void completion_pages(struct work_struct *work)
if (ret) { if (ret) {
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
SetPageError(page); SetPageError(page);
} else { } else if (done) {
SetPageUptodate(page); SetPageUptodate(page);
} }
unlock_page(page); if (done)
unlock_page(page);
} }
}
void fscrypt_decrypt_bio(struct bio *bio)
{
__fscrypt_decrypt_bio(bio, false);
}
EXPORT_SYMBOL(fscrypt_decrypt_bio);
static void completion_pages(struct work_struct *work)
{
struct fscrypt_ctx *ctx =
container_of(work, struct fscrypt_ctx, r.work);
struct bio *bio = ctx->r.bio;
__fscrypt_decrypt_bio(bio, true);
fscrypt_release_ctx(ctx); fscrypt_release_ctx(ctx);
bio_put(bio); bio_put(bio);
} }
void fscrypt_decrypt_bio_pages(struct fscrypt_ctx *ctx, struct bio *bio) void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx, struct bio *bio)
{ {
INIT_WORK(&ctx->r.work, completion_pages); INIT_WORK(&ctx->r.work, completion_pages);
ctx->r.bio = bio; ctx->r.bio = bio;
queue_work(fscrypt_read_workqueue, &ctx->r.work); fscrypt_enqueue_decrypt_work(&ctx->r.work);
} }
EXPORT_SYMBOL(fscrypt_decrypt_bio_pages); EXPORT_SYMBOL(fscrypt_enqueue_decrypt_bio);
void fscrypt_pullback_bio_page(struct page **page, bool restore) void fscrypt_pullback_bio_page(struct page **page, bool restore)
{ {
......
...@@ -45,12 +45,18 @@ static mempool_t *fscrypt_bounce_page_pool = NULL; ...@@ -45,12 +45,18 @@ static mempool_t *fscrypt_bounce_page_pool = NULL;
static LIST_HEAD(fscrypt_free_ctxs); static LIST_HEAD(fscrypt_free_ctxs);
static DEFINE_SPINLOCK(fscrypt_ctx_lock); static DEFINE_SPINLOCK(fscrypt_ctx_lock);
struct workqueue_struct *fscrypt_read_workqueue; static struct workqueue_struct *fscrypt_read_workqueue;
static DEFINE_MUTEX(fscrypt_init_mutex); static DEFINE_MUTEX(fscrypt_init_mutex);
static struct kmem_cache *fscrypt_ctx_cachep; static struct kmem_cache *fscrypt_ctx_cachep;
struct kmem_cache *fscrypt_info_cachep; struct kmem_cache *fscrypt_info_cachep;
void fscrypt_enqueue_decrypt_work(struct work_struct *work)
{
queue_work(fscrypt_read_workqueue, work);
}
EXPORT_SYMBOL(fscrypt_enqueue_decrypt_work);
/** /**
* fscrypt_release_ctx() - Releases an encryption context * fscrypt_release_ctx() - Releases an encryption context
* @ctx: The encryption context to release. * @ctx: The encryption context to release.
......
...@@ -93,7 +93,6 @@ static inline bool fscrypt_valid_enc_modes(u32 contents_mode, ...@@ -93,7 +93,6 @@ static inline bool fscrypt_valid_enc_modes(u32 contents_mode,
/* crypto.c */ /* crypto.c */
extern struct kmem_cache *fscrypt_info_cachep; extern struct kmem_cache *fscrypt_info_cachep;
extern int fscrypt_initialize(unsigned int cop_flags); extern int fscrypt_initialize(unsigned int cop_flags);
extern struct workqueue_struct *fscrypt_read_workqueue;
extern int fscrypt_do_page_crypto(const struct inode *inode, extern int fscrypt_do_page_crypto(const struct inode *inode,
fscrypt_direction_t rw, u64 lblk_num, fscrypt_direction_t rw, u64 lblk_num,
struct page *src_page, struct page *src_page,
......
...@@ -77,7 +77,7 @@ static void mpage_end_io(struct bio *bio) ...@@ -77,7 +77,7 @@ static void mpage_end_io(struct bio *bio)
if (bio->bi_status) { if (bio->bi_status) {
fscrypt_release_ctx(bio->bi_private); fscrypt_release_ctx(bio->bi_private);
} else { } else {
fscrypt_decrypt_bio_pages(bio->bi_private, bio); fscrypt_enqueue_decrypt_bio(bio->bi_private, bio);
return; return;
} }
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -104,6 +104,8 @@ static void update_general_status(struct f2fs_sb_info *sbi) ...@@ -104,6 +104,8 @@ static void update_general_status(struct f2fs_sb_info *sbi)
si->avail_nids = NM_I(sbi)->available_nids; si->avail_nids = NM_I(sbi)->available_nids;
si->alloc_nids = NM_I(sbi)->nid_cnt[PREALLOC_NID]; si->alloc_nids = NM_I(sbi)->nid_cnt[PREALLOC_NID];
si->bg_gc = sbi->bg_gc; si->bg_gc = sbi->bg_gc;
si->skipped_atomic_files[BG_GC] = sbi->skipped_atomic_files[BG_GC];
si->skipped_atomic_files[FG_GC] = sbi->skipped_atomic_files[FG_GC];
si->util_free = (int)(free_user_blocks(sbi) >> sbi->log_blocks_per_seg) si->util_free = (int)(free_user_blocks(sbi) >> sbi->log_blocks_per_seg)
* 100 / (int)(sbi->user_block_count >> sbi->log_blocks_per_seg) * 100 / (int)(sbi->user_block_count >> sbi->log_blocks_per_seg)
/ 2; / 2;
...@@ -342,6 +344,10 @@ static int stat_show(struct seq_file *s, void *v) ...@@ -342,6 +344,10 @@ static int stat_show(struct seq_file *s, void *v)
si->bg_data_blks); si->bg_data_blks);
seq_printf(s, " - node blocks : %d (%d)\n", si->node_blks, seq_printf(s, " - node blocks : %d (%d)\n", si->node_blks,
si->bg_node_blks); si->bg_node_blks);
seq_printf(s, "Skipped : atomic write %llu (%llu)\n",
si->skipped_atomic_files[BG_GC] +
si->skipped_atomic_files[FG_GC],
si->skipped_atomic_files[BG_GC]);
seq_puts(s, "\nExtent Cache:\n"); seq_puts(s, "\nExtent Cache:\n");
seq_printf(s, " - Hit Count: L1-1:%llu L1-2:%llu L2:%llu\n", seq_printf(s, " - Hit Count: L1-1:%llu L1-2:%llu L2:%llu\n",
si->hit_largest, si->hit_cached, si->hit_largest, si->hit_cached,
......
This diff is collapsed.
...@@ -49,7 +49,7 @@ static struct rb_entry *__lookup_rb_tree_slow(struct rb_root *root, ...@@ -49,7 +49,7 @@ static struct rb_entry *__lookup_rb_tree_slow(struct rb_root *root,
return NULL; return NULL;
} }
struct rb_entry *__lookup_rb_tree(struct rb_root *root, struct rb_entry *f2fs_lookup_rb_tree(struct rb_root *root,
struct rb_entry *cached_re, unsigned int ofs) struct rb_entry *cached_re, unsigned int ofs)
{ {
struct rb_entry *re; struct rb_entry *re;
...@@ -61,7 +61,7 @@ struct rb_entry *__lookup_rb_tree(struct rb_root *root, ...@@ -61,7 +61,7 @@ struct rb_entry *__lookup_rb_tree(struct rb_root *root,
return re; return re;
} }
struct rb_node **__lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi, struct rb_node **f2fs_lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi,
struct rb_root *root, struct rb_node **parent, struct rb_root *root, struct rb_node **parent,
unsigned int ofs) unsigned int ofs)
{ {
...@@ -92,7 +92,7 @@ struct rb_node **__lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi, ...@@ -92,7 +92,7 @@ struct rb_node **__lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi,
* in order to simpfy the insertion after. * in order to simpfy the insertion after.
* tree must stay unchanged between lookup and insertion. * tree must stay unchanged between lookup and insertion.
*/ */
struct rb_entry *__lookup_rb_tree_ret(struct rb_root *root, struct rb_entry *f2fs_lookup_rb_tree_ret(struct rb_root *root,
struct rb_entry *cached_re, struct rb_entry *cached_re,
unsigned int ofs, unsigned int ofs,
struct rb_entry **prev_entry, struct rb_entry **prev_entry,
...@@ -159,7 +159,7 @@ struct rb_entry *__lookup_rb_tree_ret(struct rb_root *root, ...@@ -159,7 +159,7 @@ struct rb_entry *__lookup_rb_tree_ret(struct rb_root *root,
return re; return re;
} }
bool __check_rb_tree_consistence(struct f2fs_sb_info *sbi, bool f2fs_check_rb_tree_consistence(struct f2fs_sb_info *sbi,
struct rb_root *root) struct rb_root *root)
{ {
#ifdef CONFIG_F2FS_CHECK_FS #ifdef CONFIG_F2FS_CHECK_FS
...@@ -390,7 +390,7 @@ static bool f2fs_lookup_extent_tree(struct inode *inode, pgoff_t pgofs, ...@@ -390,7 +390,7 @@ static bool f2fs_lookup_extent_tree(struct inode *inode, pgoff_t pgofs,
goto out; goto out;
} }
en = (struct extent_node *)__lookup_rb_tree(&et->root, en = (struct extent_node *)f2fs_lookup_rb_tree(&et->root,
(struct rb_entry *)et->cached_en, pgofs); (struct rb_entry *)et->cached_en, pgofs);
if (!en) if (!en)
goto out; goto out;
...@@ -470,7 +470,7 @@ static struct extent_node *__insert_extent_tree(struct inode *inode, ...@@ -470,7 +470,7 @@ static struct extent_node *__insert_extent_tree(struct inode *inode,
goto do_insert; goto do_insert;
} }
p = __lookup_rb_tree_for_insert(sbi, &et->root, &parent, ei->fofs); p = f2fs_lookup_rb_tree_for_insert(sbi, &et->root, &parent, ei->fofs);
do_insert: do_insert:
en = __attach_extent_node(sbi, et, ei, parent, p); en = __attach_extent_node(sbi, et, ei, parent, p);
if (!en) if (!en)
...@@ -520,7 +520,7 @@ static void f2fs_update_extent_tree_range(struct inode *inode, ...@@ -520,7 +520,7 @@ static void f2fs_update_extent_tree_range(struct inode *inode,
__drop_largest_extent(inode, fofs, len); __drop_largest_extent(inode, fofs, len);
/* 1. lookup first extent node in range [fofs, fofs + len - 1] */ /* 1. lookup first extent node in range [fofs, fofs + len - 1] */
en = (struct extent_node *)__lookup_rb_tree_ret(&et->root, en = (struct extent_node *)f2fs_lookup_rb_tree_ret(&et->root,
(struct rb_entry *)et->cached_en, fofs, (struct rb_entry *)et->cached_en, fofs,
(struct rb_entry **)&prev_en, (struct rb_entry **)&prev_en,
(struct rb_entry **)&next_en, (struct rb_entry **)&next_en,
...@@ -773,7 +773,7 @@ void f2fs_update_extent_cache(struct dnode_of_data *dn) ...@@ -773,7 +773,7 @@ void f2fs_update_extent_cache(struct dnode_of_data *dn)
else else
blkaddr = dn->data_blkaddr; blkaddr = dn->data_blkaddr;
fofs = start_bidx_of_node(ofs_of_node(dn->node_page), dn->inode) + fofs = f2fs_start_bidx_of_node(ofs_of_node(dn->node_page), dn->inode) +
dn->ofs_in_node; dn->ofs_in_node;
f2fs_update_extent_tree_range(dn->inode, fofs, blkaddr, 1); f2fs_update_extent_tree_range(dn->inode, fofs, blkaddr, 1);
} }
...@@ -788,7 +788,7 @@ void f2fs_update_extent_cache_range(struct dnode_of_data *dn, ...@@ -788,7 +788,7 @@ void f2fs_update_extent_cache_range(struct dnode_of_data *dn,
f2fs_update_extent_tree_range(dn->inode, fofs, blkaddr, len); f2fs_update_extent_tree_range(dn->inode, fofs, blkaddr, len);
} }
void init_extent_cache_info(struct f2fs_sb_info *sbi) void f2fs_init_extent_cache_info(struct f2fs_sb_info *sbi)
{ {
INIT_RADIX_TREE(&sbi->extent_tree_root, GFP_NOIO); INIT_RADIX_TREE(&sbi->extent_tree_root, GFP_NOIO);
mutex_init(&sbi->extent_tree_lock); mutex_init(&sbi->extent_tree_lock);
...@@ -800,7 +800,7 @@ void init_extent_cache_info(struct f2fs_sb_info *sbi) ...@@ -800,7 +800,7 @@ void init_extent_cache_info(struct f2fs_sb_info *sbi)
atomic_set(&sbi->total_ext_node, 0); atomic_set(&sbi->total_ext_node, 0);
} }
int __init create_extent_cache(void) int __init f2fs_create_extent_cache(void)
{ {
extent_tree_slab = f2fs_kmem_cache_create("f2fs_extent_tree", extent_tree_slab = f2fs_kmem_cache_create("f2fs_extent_tree",
sizeof(struct extent_tree)); sizeof(struct extent_tree));
...@@ -815,7 +815,7 @@ int __init create_extent_cache(void) ...@@ -815,7 +815,7 @@ int __init create_extent_cache(void)
return 0; return 0;
} }
void destroy_extent_cache(void) void f2fs_destroy_extent_cache(void)
{ {
kmem_cache_destroy(extent_node_slab); kmem_cache_destroy(extent_node_slab);
kmem_cache_destroy(extent_tree_slab); kmem_cache_destroy(extent_tree_slab);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -36,8 +36,6 @@ struct f2fs_gc_kthread { ...@@ -36,8 +36,6 @@ struct f2fs_gc_kthread {
unsigned int no_gc_sleep_time; unsigned int no_gc_sleep_time;
/* for changing gc mode */ /* for changing gc mode */
unsigned int gc_idle;
unsigned int gc_urgent;
unsigned int gc_wake; unsigned int gc_wake;
}; };
......
This diff is collapsed.
This diff is collapsed.
...@@ -37,7 +37,7 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode) ...@@ -37,7 +37,7 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
f2fs_lock_op(sbi); f2fs_lock_op(sbi);
if (!alloc_nid(sbi, &ino)) { if (!f2fs_alloc_nid(sbi, &ino)) {
f2fs_unlock_op(sbi); f2fs_unlock_op(sbi);
err = -ENOSPC; err = -ENOSPC;
goto fail; goto fail;
...@@ -54,6 +54,9 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode) ...@@ -54,6 +54,9 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
F2FS_I(inode)->i_crtime = current_time(inode); F2FS_I(inode)->i_crtime = current_time(inode);
inode->i_generation = sbi->s_next_generation++; inode->i_generation = sbi->s_next_generation++;
if (S_ISDIR(inode->i_mode))
F2FS_I(inode)->i_current_depth = 1;
err = insert_inode_locked(inode); err = insert_inode_locked(inode);
if (err) { if (err) {
err = -EINVAL; err = -EINVAL;
...@@ -61,7 +64,7 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode) ...@@ -61,7 +64,7 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
} }
if (f2fs_sb_has_project_quota(sbi->sb) && if (f2fs_sb_has_project_quota(sbi->sb) &&
(F2FS_I(dir)->i_flags & FS_PROJINHERIT_FL)) (F2FS_I(dir)->i_flags & F2FS_PROJINHERIT_FL))
F2FS_I(inode)->i_projid = F2FS_I(dir)->i_projid; F2FS_I(inode)->i_projid = F2FS_I(dir)->i_projid;
else else
F2FS_I(inode)->i_projid = make_kprojid(&init_user_ns, F2FS_I(inode)->i_projid = make_kprojid(&init_user_ns,
...@@ -116,9 +119,9 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode) ...@@ -116,9 +119,9 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
f2fs_mask_flags(mode, F2FS_I(dir)->i_flags & F2FS_FL_INHERITED); f2fs_mask_flags(mode, F2FS_I(dir)->i_flags & F2FS_FL_INHERITED);
if (S_ISDIR(inode->i_mode)) if (S_ISDIR(inode->i_mode))
F2FS_I(inode)->i_flags |= FS_INDEX_FL; F2FS_I(inode)->i_flags |= F2FS_INDEX_FL;
if (F2FS_I(inode)->i_flags & FS_PROJINHERIT_FL) if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL)
set_inode_flag(inode, FI_PROJ_INHERIT); set_inode_flag(inode, FI_PROJ_INHERIT);
trace_f2fs_new_inode(inode, 0); trace_f2fs_new_inode(inode, 0);
...@@ -193,7 +196,7 @@ static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode * ...@@ -193,7 +196,7 @@ static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode *
up_read(&sbi->sb_lock); up_read(&sbi->sb_lock);
} }
int update_extension_list(struct f2fs_sb_info *sbi, const char *name, int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name,
bool hot, bool set) bool hot, bool set)
{ {
__u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
...@@ -292,7 +295,7 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode, ...@@ -292,7 +295,7 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
goto out; goto out;
f2fs_unlock_op(sbi); f2fs_unlock_op(sbi);
alloc_nid_done(sbi, ino); f2fs_alloc_nid_done(sbi, ino);
d_instantiate_new(dentry, inode); d_instantiate_new(dentry, inode);
...@@ -302,7 +305,7 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode, ...@@ -302,7 +305,7 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
f2fs_balance_fs(sbi, true); f2fs_balance_fs(sbi, true);
return 0; return 0;
out: out:
handle_failed_inode(inode); f2fs_handle_failed_inode(inode);
return err; return err;
} }
...@@ -397,7 +400,7 @@ static int __recover_dot_dentries(struct inode *dir, nid_t pino) ...@@ -397,7 +400,7 @@ static int __recover_dot_dentries(struct inode *dir, nid_t pino)
err = PTR_ERR(page); err = PTR_ERR(page);
goto out; goto out;
} else { } else {
err = __f2fs_add_link(dir, &dot, NULL, dir->i_ino, S_IFDIR); err = f2fs_do_add_link(dir, &dot, NULL, dir->i_ino, S_IFDIR);
if (err) if (err)
goto out; goto out;
} }
...@@ -408,7 +411,7 @@ static int __recover_dot_dentries(struct inode *dir, nid_t pino) ...@@ -408,7 +411,7 @@ static int __recover_dot_dentries(struct inode *dir, nid_t pino)
else if (IS_ERR(page)) else if (IS_ERR(page))
err = PTR_ERR(page); err = PTR_ERR(page);
else else
err = __f2fs_add_link(dir, &dotdot, NULL, pino, S_IFDIR); err = f2fs_do_add_link(dir, &dotdot, NULL, pino, S_IFDIR);
out: out:
if (!err) if (!err)
clear_inode_flag(dir, FI_INLINE_DOTS); clear_inode_flag(dir, FI_INLINE_DOTS);
...@@ -520,7 +523,7 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry) ...@@ -520,7 +523,7 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry)
f2fs_balance_fs(sbi, true); f2fs_balance_fs(sbi, true);
f2fs_lock_op(sbi); f2fs_lock_op(sbi);
err = acquire_orphan_inode(sbi); err = f2fs_acquire_orphan_inode(sbi);
if (err) { if (err) {
f2fs_unlock_op(sbi); f2fs_unlock_op(sbi);
f2fs_put_page(page, 0); f2fs_put_page(page, 0);
...@@ -585,9 +588,9 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, ...@@ -585,9 +588,9 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
f2fs_lock_op(sbi); f2fs_lock_op(sbi);
err = f2fs_add_link(dentry, inode); err = f2fs_add_link(dentry, inode);
if (err) if (err)
goto out_handle_failed_inode; goto out_f2fs_handle_failed_inode;
f2fs_unlock_op(sbi); f2fs_unlock_op(sbi);
alloc_nid_done(sbi, inode->i_ino); f2fs_alloc_nid_done(sbi, inode->i_ino);
err = fscrypt_encrypt_symlink(inode, symname, len, &disk_link); err = fscrypt_encrypt_symlink(inode, symname, len, &disk_link);
if (err) if (err)
...@@ -620,8 +623,8 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, ...@@ -620,8 +623,8 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
f2fs_balance_fs(sbi, true); f2fs_balance_fs(sbi, true);
goto out_free_encrypted_link; goto out_free_encrypted_link;
out_handle_failed_inode: out_f2fs_handle_failed_inode:
handle_failed_inode(inode); f2fs_handle_failed_inode(inode);
out_free_encrypted_link: out_free_encrypted_link:
if (disk_link.name != (unsigned char *)symname) if (disk_link.name != (unsigned char *)symname)
kfree(disk_link.name); kfree(disk_link.name);
...@@ -657,7 +660,7 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) ...@@ -657,7 +660,7 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
goto out_fail; goto out_fail;
f2fs_unlock_op(sbi); f2fs_unlock_op(sbi);
alloc_nid_done(sbi, inode->i_ino); f2fs_alloc_nid_done(sbi, inode->i_ino);
d_instantiate_new(dentry, inode); d_instantiate_new(dentry, inode);
...@@ -669,7 +672,7 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) ...@@ -669,7 +672,7 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
out_fail: out_fail:
clear_inode_flag(inode, FI_INC_LINK); clear_inode_flag(inode, FI_INC_LINK);
handle_failed_inode(inode); f2fs_handle_failed_inode(inode);
return err; return err;
} }
...@@ -708,7 +711,7 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry, ...@@ -708,7 +711,7 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry,
goto out; goto out;
f2fs_unlock_op(sbi); f2fs_unlock_op(sbi);
alloc_nid_done(sbi, inode->i_ino); f2fs_alloc_nid_done(sbi, inode->i_ino);
d_instantiate_new(dentry, inode); d_instantiate_new(dentry, inode);
...@@ -718,7 +721,7 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry, ...@@ -718,7 +721,7 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry,
f2fs_balance_fs(sbi, true); f2fs_balance_fs(sbi, true);
return 0; return 0;
out: out:
handle_failed_inode(inode); f2fs_handle_failed_inode(inode);
return err; return err;
} }
...@@ -747,7 +750,7 @@ static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry, ...@@ -747,7 +750,7 @@ static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry,
} }
f2fs_lock_op(sbi); f2fs_lock_op(sbi);
err = acquire_orphan_inode(sbi); err = f2fs_acquire_orphan_inode(sbi);
if (err) if (err)
goto out; goto out;
...@@ -759,8 +762,8 @@ static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry, ...@@ -759,8 +762,8 @@ static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry,
* add this non-linked tmpfile to orphan list, in this way we could * add this non-linked tmpfile to orphan list, in this way we could
* remove all unused data of tmpfile after abnormal power-off. * remove all unused data of tmpfile after abnormal power-off.
*/ */
add_orphan_inode(inode); f2fs_add_orphan_inode(inode);
alloc_nid_done(sbi, inode->i_ino); f2fs_alloc_nid_done(sbi, inode->i_ino);
if (whiteout) { if (whiteout) {
f2fs_i_links_write(inode, false); f2fs_i_links_write(inode, false);
...@@ -776,9 +779,9 @@ static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry, ...@@ -776,9 +779,9 @@ static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry,
return 0; return 0;
release_out: release_out:
release_orphan_inode(sbi); f2fs_release_orphan_inode(sbi);
out: out:
handle_failed_inode(inode); f2fs_handle_failed_inode(inode);
return err; return err;
} }
...@@ -885,7 +888,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -885,7 +888,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
f2fs_lock_op(sbi); f2fs_lock_op(sbi);
err = acquire_orphan_inode(sbi); err = f2fs_acquire_orphan_inode(sbi);
if (err) if (err)
goto put_out_dir; goto put_out_dir;
...@@ -899,9 +902,9 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -899,9 +902,9 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
up_write(&F2FS_I(new_inode)->i_sem); up_write(&F2FS_I(new_inode)->i_sem);
if (!new_inode->i_nlink) if (!new_inode->i_nlink)
add_orphan_inode(new_inode); f2fs_add_orphan_inode(new_inode);
else else
release_orphan_inode(sbi); f2fs_release_orphan_inode(sbi);
} else { } else {
f2fs_balance_fs(sbi, true); f2fs_balance_fs(sbi, true);
...@@ -969,8 +972,12 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -969,8 +972,12 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
f2fs_put_page(old_dir_page, 0); f2fs_put_page(old_dir_page, 0);
f2fs_i_links_write(old_dir, false); f2fs_i_links_write(old_dir, false);
} }
if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT) if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT) {
add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO); f2fs_add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO);
if (S_ISDIR(old_inode->i_mode))
f2fs_add_ino_entry(sbi, old_inode->i_ino,
TRANS_DIR_INO);
}
f2fs_unlock_op(sbi); f2fs_unlock_op(sbi);
...@@ -1121,8 +1128,8 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1121,8 +1128,8 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
f2fs_mark_inode_dirty_sync(new_dir, false); f2fs_mark_inode_dirty_sync(new_dir, false);
if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT) { if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT) {
add_ino_entry(sbi, old_dir->i_ino, TRANS_DIR_INO); f2fs_add_ino_entry(sbi, old_dir->i_ino, TRANS_DIR_INO);
add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO); f2fs_add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO);
} }
f2fs_unlock_op(sbi); f2fs_unlock_op(sbi);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
(GET_SEGOFF_FROM_SEG0(sbi, blk_addr) & ((sbi)->blocks_per_seg - 1)) (GET_SEGOFF_FROM_SEG0(sbi, blk_addr) & ((sbi)->blocks_per_seg - 1))
#define GET_SEGNO(sbi, blk_addr) \ #define GET_SEGNO(sbi, blk_addr) \
((((blk_addr) == NULL_ADDR) || ((blk_addr) == NEW_ADDR)) ? \ ((!is_valid_blkaddr(blk_addr)) ? \
NULL_SEGNO : GET_L2R_SEGNO(FREE_I(sbi), \ NULL_SEGNO : GET_L2R_SEGNO(FREE_I(sbi), \
GET_SEGNO_FROM_SEG0(sbi, blk_addr))) GET_SEGNO_FROM_SEG0(sbi, blk_addr)))
#define BLKS_PER_SEC(sbi) \ #define BLKS_PER_SEC(sbi) \
...@@ -215,6 +215,8 @@ struct segment_allocation { ...@@ -215,6 +215,8 @@ struct segment_allocation {
#define IS_DUMMY_WRITTEN_PAGE(page) \ #define IS_DUMMY_WRITTEN_PAGE(page) \
(page_private(page) == (unsigned long)DUMMY_WRITTEN_PAGE) (page_private(page) == (unsigned long)DUMMY_WRITTEN_PAGE)
#define MAX_SKIP_ATOMIC_COUNT 16
struct inmem_pages { struct inmem_pages {
struct list_head list; struct list_head list;
struct page *page; struct page *page;
...@@ -375,6 +377,7 @@ static inline void seg_info_to_sit_page(struct f2fs_sb_info *sbi, ...@@ -375,6 +377,7 @@ static inline void seg_info_to_sit_page(struct f2fs_sb_info *sbi,
int i; int i;
raw_sit = (struct f2fs_sit_block *)page_address(page); raw_sit = (struct f2fs_sit_block *)page_address(page);
memset(raw_sit, 0, PAGE_SIZE);
for (i = 0; i < end - start; i++) { for (i = 0; i < end - start; i++) {
rs = &raw_sit->entries[i]; rs = &raw_sit->entries[i];
se = get_seg_entry(sbi, start + i); se = get_seg_entry(sbi, start + i);
...@@ -742,12 +745,23 @@ static inline void set_to_next_sit(struct sit_info *sit_i, unsigned int start) ...@@ -742,12 +745,23 @@ static inline void set_to_next_sit(struct sit_info *sit_i, unsigned int start)
#endif #endif
} }
static inline unsigned long long get_mtime(struct f2fs_sb_info *sbi) static inline unsigned long long get_mtime(struct f2fs_sb_info *sbi,
bool base_time)
{ {
struct sit_info *sit_i = SIT_I(sbi); struct sit_info *sit_i = SIT_I(sbi);
time64_t now = ktime_get_real_seconds(); time64_t diff, now = ktime_get_real_seconds();
if (now >= sit_i->mounted_time)
return sit_i->elapsed_time + now - sit_i->mounted_time;
return sit_i->elapsed_time + now - sit_i->mounted_time; /* system time is set to the past */
if (!base_time) {
diff = sit_i->mounted_time - now;
if (sit_i->elapsed_time >= diff)
return sit_i->elapsed_time - diff;
return 0;
}
return sit_i->elapsed_time;
} }
static inline void set_summary(struct f2fs_summary *sum, nid_t nid, static inline void set_summary(struct f2fs_summary *sum, nid_t nid,
...@@ -771,15 +785,6 @@ static inline block_t sum_blk_addr(struct f2fs_sb_info *sbi, int base, int type) ...@@ -771,15 +785,6 @@ static inline block_t sum_blk_addr(struct f2fs_sb_info *sbi, int base, int type)
- (base + 1) + type; - (base + 1) + type;
} }
static inline bool no_fggc_candidate(struct f2fs_sb_info *sbi,
unsigned int secno)
{
if (get_valid_blocks(sbi, GET_SEG_FROM_SEC(sbi, secno), true) >
sbi->fggc_threshold)
return true;
return false;
}
static inline bool sec_usage_check(struct f2fs_sb_info *sbi, unsigned int secno) static inline bool sec_usage_check(struct f2fs_sb_info *sbi, unsigned int secno)
{ {
if (IS_CURSEC(sbi, secno) || (sbi->cur_victim_sec == secno)) if (IS_CURSEC(sbi, secno) || (sbi->cur_victim_sec == secno))
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment