提交 d54d35c5 编写于 作者: L 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
  ...
...@@ -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;
} }
} }
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include <trace/events/f2fs.h> #include <trace/events/f2fs.h>
static struct kmem_cache *ino_entry_slab; static struct kmem_cache *ino_entry_slab;
struct kmem_cache *inode_entry_slab; struct kmem_cache *f2fs_inode_entry_slab;
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io) void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io)
{ {
...@@ -36,7 +36,7 @@ void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io) ...@@ -36,7 +36,7 @@ void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io)
/* /*
* We guarantee no failure on the returned page. * We guarantee no failure on the returned page.
*/ */
struct page *grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index) struct page *f2fs_grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)
{ {
struct address_space *mapping = META_MAPPING(sbi); struct address_space *mapping = META_MAPPING(sbi);
struct page *page = NULL; struct page *page = NULL;
...@@ -100,24 +100,27 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index, ...@@ -100,24 +100,27 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
* readonly and make sure do not write checkpoint with non-uptodate * readonly and make sure do not write checkpoint with non-uptodate
* meta page. * meta page.
*/ */
if (unlikely(!PageUptodate(page))) if (unlikely(!PageUptodate(page))) {
memset(page_address(page), 0, PAGE_SIZE);
f2fs_stop_checkpoint(sbi, false); f2fs_stop_checkpoint(sbi, false);
}
out: out:
return page; return page;
} }
struct page *get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index) struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)
{ {
return __get_meta_page(sbi, index, true); return __get_meta_page(sbi, index, true);
} }
/* for POR only */ /* for POR only */
struct page *get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index) struct page *f2fs_get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index)
{ {
return __get_meta_page(sbi, index, false); return __get_meta_page(sbi, index, false);
} }
bool is_valid_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr, int type) bool f2fs_is_valid_meta_blkaddr(struct f2fs_sb_info *sbi,
block_t blkaddr, int type)
{ {
switch (type) { switch (type) {
case META_NAT: case META_NAT:
...@@ -151,7 +154,7 @@ bool is_valid_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr, int type) ...@@ -151,7 +154,7 @@ bool is_valid_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr, int type)
/* /*
* Readahead CP/NAT/SIT/SSA pages * Readahead CP/NAT/SIT/SSA pages
*/ */
int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
int type, bool sync) int type, bool sync)
{ {
struct page *page; struct page *page;
...@@ -173,7 +176,7 @@ int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, ...@@ -173,7 +176,7 @@ int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
blk_start_plug(&plug); blk_start_plug(&plug);
for (; nrpages-- > 0; blkno++) { for (; nrpages-- > 0; blkno++) {
if (!is_valid_blkaddr(sbi, blkno, type)) if (!f2fs_is_valid_meta_blkaddr(sbi, blkno, type))
goto out; goto out;
switch (type) { switch (type) {
...@@ -217,7 +220,7 @@ int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, ...@@ -217,7 +220,7 @@ int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
return blkno - start; return blkno - start;
} }
void ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index) void f2fs_ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index)
{ {
struct page *page; struct page *page;
bool readahead = false; bool readahead = false;
...@@ -228,7 +231,7 @@ void ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index) ...@@ -228,7 +231,7 @@ void ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index)
f2fs_put_page(page, 0); f2fs_put_page(page, 0);
if (readahead) if (readahead)
ra_meta_pages(sbi, index, BIO_MAX_PAGES, META_POR, true); f2fs_ra_meta_pages(sbi, index, BIO_MAX_PAGES, META_POR, true);
} }
static int __f2fs_write_meta_page(struct page *page, static int __f2fs_write_meta_page(struct page *page,
...@@ -249,7 +252,7 @@ static int __f2fs_write_meta_page(struct page *page, ...@@ -249,7 +252,7 @@ static int __f2fs_write_meta_page(struct page *page,
if (wbc->for_reclaim && page->index < GET_SUM_BLOCK(sbi, 0)) if (wbc->for_reclaim && page->index < GET_SUM_BLOCK(sbi, 0))
goto redirty_out; goto redirty_out;
write_meta_page(sbi, page, io_type); f2fs_do_write_meta_page(sbi, page, io_type);
dec_page_count(sbi, F2FS_DIRTY_META); dec_page_count(sbi, F2FS_DIRTY_META);
if (wbc->for_reclaim) if (wbc->for_reclaim)
...@@ -294,7 +297,7 @@ static int f2fs_write_meta_pages(struct address_space *mapping, ...@@ -294,7 +297,7 @@ static int f2fs_write_meta_pages(struct address_space *mapping,
trace_f2fs_writepages(mapping->host, wbc, META); trace_f2fs_writepages(mapping->host, wbc, META);
diff = nr_pages_to_write(sbi, META, wbc); diff = nr_pages_to_write(sbi, META, wbc);
written = sync_meta_pages(sbi, META, wbc->nr_to_write, FS_META_IO); written = f2fs_sync_meta_pages(sbi, META, wbc->nr_to_write, FS_META_IO);
mutex_unlock(&sbi->cp_mutex); mutex_unlock(&sbi->cp_mutex);
wbc->nr_to_write = max((long)0, wbc->nr_to_write - written - diff); wbc->nr_to_write = max((long)0, wbc->nr_to_write - written - diff);
return 0; return 0;
...@@ -305,7 +308,7 @@ static int f2fs_write_meta_pages(struct address_space *mapping, ...@@ -305,7 +308,7 @@ static int f2fs_write_meta_pages(struct address_space *mapping,
return 0; return 0;
} }
long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type, long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
long nr_to_write, enum iostat_type io_type) long nr_to_write, enum iostat_type io_type)
{ {
struct address_space *mapping = META_MAPPING(sbi); struct address_space *mapping = META_MAPPING(sbi);
...@@ -382,7 +385,7 @@ static int f2fs_set_meta_page_dirty(struct page *page) ...@@ -382,7 +385,7 @@ static int f2fs_set_meta_page_dirty(struct page *page)
if (!PageUptodate(page)) if (!PageUptodate(page))
SetPageUptodate(page); SetPageUptodate(page);
if (!PageDirty(page)) { if (!PageDirty(page)) {
f2fs_set_page_dirty_nobuffers(page); __set_page_dirty_nobuffers(page);
inc_page_count(F2FS_P_SB(page), F2FS_DIRTY_META); inc_page_count(F2FS_P_SB(page), F2FS_DIRTY_META);
SetPagePrivate(page); SetPagePrivate(page);
f2fs_trace_pid(page); f2fs_trace_pid(page);
...@@ -455,20 +458,20 @@ static void __remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type) ...@@ -455,20 +458,20 @@ static void __remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
spin_unlock(&im->ino_lock); spin_unlock(&im->ino_lock);
} }
void add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type) void f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
{ {
/* add new dirty ino entry into list */ /* add new dirty ino entry into list */
__add_ino_entry(sbi, ino, 0, type); __add_ino_entry(sbi, ino, 0, type);
} }
void remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type) void f2fs_remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
{ {
/* remove dirty ino entry from list */ /* remove dirty ino entry from list */
__remove_ino_entry(sbi, ino, type); __remove_ino_entry(sbi, ino, type);
} }
/* mode should be APPEND_INO or UPDATE_INO */ /* mode should be APPEND_INO or UPDATE_INO */
bool exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode) bool f2fs_exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode)
{ {
struct inode_management *im = &sbi->im[mode]; struct inode_management *im = &sbi->im[mode];
struct ino_entry *e; struct ino_entry *e;
...@@ -479,7 +482,7 @@ bool exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode) ...@@ -479,7 +482,7 @@ bool exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode)
return e ? true : false; return e ? true : false;
} }
void release_ino_entry(struct f2fs_sb_info *sbi, bool all) void f2fs_release_ino_entry(struct f2fs_sb_info *sbi, bool all)
{ {
struct ino_entry *e, *tmp; struct ino_entry *e, *tmp;
int i; int i;
...@@ -498,13 +501,13 @@ void release_ino_entry(struct f2fs_sb_info *sbi, bool all) ...@@ -498,13 +501,13 @@ void release_ino_entry(struct f2fs_sb_info *sbi, bool all)
} }
} }
void set_dirty_device(struct f2fs_sb_info *sbi, nid_t ino, void f2fs_set_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
unsigned int devidx, int type) unsigned int devidx, int type)
{ {
__add_ino_entry(sbi, ino, devidx, type); __add_ino_entry(sbi, ino, devidx, type);
} }
bool is_dirty_device(struct f2fs_sb_info *sbi, nid_t ino, bool f2fs_is_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
unsigned int devidx, int type) unsigned int devidx, int type)
{ {
struct inode_management *im = &sbi->im[type]; struct inode_management *im = &sbi->im[type];
...@@ -519,7 +522,7 @@ bool is_dirty_device(struct f2fs_sb_info *sbi, nid_t ino, ...@@ -519,7 +522,7 @@ bool is_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
return is_dirty; return is_dirty;
} }
int acquire_orphan_inode(struct f2fs_sb_info *sbi) int f2fs_acquire_orphan_inode(struct f2fs_sb_info *sbi)
{ {
struct inode_management *im = &sbi->im[ORPHAN_INO]; struct inode_management *im = &sbi->im[ORPHAN_INO];
int err = 0; int err = 0;
...@@ -542,7 +545,7 @@ int acquire_orphan_inode(struct f2fs_sb_info *sbi) ...@@ -542,7 +545,7 @@ int acquire_orphan_inode(struct f2fs_sb_info *sbi)
return err; return err;
} }
void release_orphan_inode(struct f2fs_sb_info *sbi) void f2fs_release_orphan_inode(struct f2fs_sb_info *sbi)
{ {
struct inode_management *im = &sbi->im[ORPHAN_INO]; struct inode_management *im = &sbi->im[ORPHAN_INO];
...@@ -552,14 +555,14 @@ void release_orphan_inode(struct f2fs_sb_info *sbi) ...@@ -552,14 +555,14 @@ void release_orphan_inode(struct f2fs_sb_info *sbi)
spin_unlock(&im->ino_lock); spin_unlock(&im->ino_lock);
} }
void add_orphan_inode(struct inode *inode) void f2fs_add_orphan_inode(struct inode *inode)
{ {
/* add new orphan ino entry into list */ /* add new orphan ino entry into list */
__add_ino_entry(F2FS_I_SB(inode), inode->i_ino, 0, ORPHAN_INO); __add_ino_entry(F2FS_I_SB(inode), inode->i_ino, 0, ORPHAN_INO);
update_inode_page(inode); f2fs_update_inode_page(inode);
} }
void remove_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) void f2fs_remove_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
{ {
/* remove orphan entry from orphan list */ /* remove orphan entry from orphan list */
__remove_ino_entry(sbi, ino, ORPHAN_INO); __remove_ino_entry(sbi, ino, ORPHAN_INO);
...@@ -569,7 +572,7 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) ...@@ -569,7 +572,7 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
{ {
struct inode *inode; struct inode *inode;
struct node_info ni; struct node_info ni;
int err = acquire_orphan_inode(sbi); int err = f2fs_acquire_orphan_inode(sbi);
if (err) if (err)
goto err_out; goto err_out;
...@@ -587,16 +590,17 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) ...@@ -587,16 +590,17 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
} }
err = dquot_initialize(inode); err = dquot_initialize(inode);
if (err) if (err) {
iput(inode);
goto err_out; goto err_out;
}
dquot_initialize(inode);
clear_nlink(inode); clear_nlink(inode);
/* truncate all the data during iput */ /* truncate all the data during iput */
iput(inode); iput(inode);
get_node_info(sbi, ino, &ni); f2fs_get_node_info(sbi, ino, &ni);
/* ENOMEM was fully retried in f2fs_evict_inode. */ /* ENOMEM was fully retried in f2fs_evict_inode. */
if (ni.blk_addr != NULL_ADDR) { if (ni.blk_addr != NULL_ADDR) {
...@@ -614,7 +618,7 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) ...@@ -614,7 +618,7 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
return err; return err;
} }
int recover_orphan_inodes(struct f2fs_sb_info *sbi) int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi)
{ {
block_t start_blk, orphan_blocks, i, j; block_t start_blk, orphan_blocks, i, j;
unsigned int s_flags = sbi->sb->s_flags; unsigned int s_flags = sbi->sb->s_flags;
...@@ -642,10 +646,10 @@ int recover_orphan_inodes(struct f2fs_sb_info *sbi) ...@@ -642,10 +646,10 @@ int recover_orphan_inodes(struct f2fs_sb_info *sbi)
start_blk = __start_cp_addr(sbi) + 1 + __cp_payload(sbi); start_blk = __start_cp_addr(sbi) + 1 + __cp_payload(sbi);
orphan_blocks = __start_sum_addr(sbi) - 1 - __cp_payload(sbi); orphan_blocks = __start_sum_addr(sbi) - 1 - __cp_payload(sbi);
ra_meta_pages(sbi, start_blk, orphan_blocks, META_CP, true); f2fs_ra_meta_pages(sbi, start_blk, orphan_blocks, META_CP, true);
for (i = 0; i < orphan_blocks; i++) { for (i = 0; i < orphan_blocks; i++) {
struct page *page = get_meta_page(sbi, start_blk + i); struct page *page = f2fs_get_meta_page(sbi, start_blk + i);
struct f2fs_orphan_block *orphan_blk; struct f2fs_orphan_block *orphan_blk;
orphan_blk = (struct f2fs_orphan_block *)page_address(page); orphan_blk = (struct f2fs_orphan_block *)page_address(page);
...@@ -695,7 +699,7 @@ static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk) ...@@ -695,7 +699,7 @@ static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk)
/* loop for each orphan inode entry and write them in Jornal block */ /* loop for each orphan inode entry and write them in Jornal block */
list_for_each_entry(orphan, head, list) { list_for_each_entry(orphan, head, list) {
if (!page) { if (!page) {
page = grab_meta_page(sbi, start_blk++); page = f2fs_grab_meta_page(sbi, start_blk++);
orphan_blk = orphan_blk =
(struct f2fs_orphan_block *)page_address(page); (struct f2fs_orphan_block *)page_address(page);
memset(orphan_blk, 0, sizeof(*orphan_blk)); memset(orphan_blk, 0, sizeof(*orphan_blk));
...@@ -737,7 +741,7 @@ static int get_checkpoint_version(struct f2fs_sb_info *sbi, block_t cp_addr, ...@@ -737,7 +741,7 @@ static int get_checkpoint_version(struct f2fs_sb_info *sbi, block_t cp_addr,
size_t crc_offset = 0; size_t crc_offset = 0;
__u32 crc = 0; __u32 crc = 0;
*cp_page = get_meta_page(sbi, cp_addr); *cp_page = f2fs_get_meta_page(sbi, cp_addr);
*cp_block = (struct f2fs_checkpoint *)page_address(*cp_page); *cp_block = (struct f2fs_checkpoint *)page_address(*cp_page);
crc_offset = le32_to_cpu((*cp_block)->checksum_offset); crc_offset = le32_to_cpu((*cp_block)->checksum_offset);
...@@ -790,7 +794,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi, ...@@ -790,7 +794,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
return NULL; return NULL;
} }
int get_valid_checkpoint(struct f2fs_sb_info *sbi) int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi)
{ {
struct f2fs_checkpoint *cp_block; struct f2fs_checkpoint *cp_block;
struct f2fs_super_block *fsb = sbi->raw_super; struct f2fs_super_block *fsb = sbi->raw_super;
...@@ -834,7 +838,7 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi) ...@@ -834,7 +838,7 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi)
memcpy(sbi->ckpt, cp_block, blk_size); memcpy(sbi->ckpt, cp_block, blk_size);
/* Sanity checking of checkpoint */ /* Sanity checking of checkpoint */
if (sanity_check_ckpt(sbi)) if (f2fs_sanity_check_ckpt(sbi))
goto free_fail_no_cp; goto free_fail_no_cp;
if (cur_page == cp1) if (cur_page == cp1)
...@@ -853,7 +857,7 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi) ...@@ -853,7 +857,7 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi)
void *sit_bitmap_ptr; void *sit_bitmap_ptr;
unsigned char *ckpt = (unsigned char *)sbi->ckpt; unsigned char *ckpt = (unsigned char *)sbi->ckpt;
cur_page = get_meta_page(sbi, cp_blk_no + i); cur_page = f2fs_get_meta_page(sbi, cp_blk_no + i);
sit_bitmap_ptr = page_address(cur_page); sit_bitmap_ptr = page_address(cur_page);
memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size); memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size);
f2fs_put_page(cur_page, 1); f2fs_put_page(cur_page, 1);
...@@ -898,7 +902,7 @@ static void __remove_dirty_inode(struct inode *inode, enum inode_type type) ...@@ -898,7 +902,7 @@ static void __remove_dirty_inode(struct inode *inode, enum inode_type type)
stat_dec_dirty_inode(F2FS_I_SB(inode), type); stat_dec_dirty_inode(F2FS_I_SB(inode), type);
} }
void update_dirty_page(struct inode *inode, struct page *page) void f2fs_update_dirty_page(struct inode *inode, struct page *page)
{ {
struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
enum inode_type type = S_ISDIR(inode->i_mode) ? DIR_INODE : FILE_INODE; enum inode_type type = S_ISDIR(inode->i_mode) ? DIR_INODE : FILE_INODE;
...@@ -917,7 +921,7 @@ void update_dirty_page(struct inode *inode, struct page *page) ...@@ -917,7 +921,7 @@ void update_dirty_page(struct inode *inode, struct page *page)
f2fs_trace_pid(page); f2fs_trace_pid(page);
} }
void remove_dirty_inode(struct inode *inode) void f2fs_remove_dirty_inode(struct inode *inode)
{ {
struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
enum inode_type type = S_ISDIR(inode->i_mode) ? DIR_INODE : FILE_INODE; enum inode_type type = S_ISDIR(inode->i_mode) ? DIR_INODE : FILE_INODE;
...@@ -934,7 +938,7 @@ void remove_dirty_inode(struct inode *inode) ...@@ -934,7 +938,7 @@ void remove_dirty_inode(struct inode *inode)
spin_unlock(&sbi->inode_lock[type]); spin_unlock(&sbi->inode_lock[type]);
} }
int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type) int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
{ {
struct list_head *head; struct list_head *head;
struct inode *inode; struct inode *inode;
...@@ -1017,7 +1021,7 @@ int f2fs_sync_inode_meta(struct f2fs_sb_info *sbi) ...@@ -1017,7 +1021,7 @@ int f2fs_sync_inode_meta(struct f2fs_sb_info *sbi)
/* it's on eviction */ /* it's on eviction */
if (is_inode_flag_set(inode, FI_DIRTY_INODE)) if (is_inode_flag_set(inode, FI_DIRTY_INODE))
update_inode_page(inode); f2fs_update_inode_page(inode);
iput(inode); iput(inode);
} }
} }
...@@ -1057,7 +1061,7 @@ static int block_operations(struct f2fs_sb_info *sbi) ...@@ -1057,7 +1061,7 @@ static int block_operations(struct f2fs_sb_info *sbi)
/* write all the dirty dentry pages */ /* write all the dirty dentry pages */
if (get_pages(sbi, F2FS_DIRTY_DENTS)) { if (get_pages(sbi, F2FS_DIRTY_DENTS)) {
f2fs_unlock_all(sbi); f2fs_unlock_all(sbi);
err = sync_dirty_inodes(sbi, DIR_INODE); err = f2fs_sync_dirty_inodes(sbi, DIR_INODE);
if (err) if (err)
goto out; goto out;
cond_resched(); cond_resched();
...@@ -1085,7 +1089,9 @@ static int block_operations(struct f2fs_sb_info *sbi) ...@@ -1085,7 +1089,9 @@ static int block_operations(struct f2fs_sb_info *sbi)
if (get_pages(sbi, F2FS_DIRTY_NODES)) { if (get_pages(sbi, F2FS_DIRTY_NODES)) {
up_write(&sbi->node_write); up_write(&sbi->node_write);
err = sync_node_pages(sbi, &wbc, false, FS_CP_NODE_IO); atomic_inc(&sbi->wb_sync_req[NODE]);
err = f2fs_sync_node_pages(sbi, &wbc, false, FS_CP_NODE_IO);
atomic_dec(&sbi->wb_sync_req[NODE]);
if (err) { if (err) {
up_write(&sbi->node_change); up_write(&sbi->node_change);
f2fs_unlock_all(sbi); f2fs_unlock_all(sbi);
...@@ -1179,10 +1185,10 @@ static void commit_checkpoint(struct f2fs_sb_info *sbi, ...@@ -1179,10 +1185,10 @@ static void commit_checkpoint(struct f2fs_sb_info *sbi,
/* /*
* pagevec_lookup_tag and lock_page again will take * pagevec_lookup_tag and lock_page again will take
* some extra time. Therefore, update_meta_pages and * some extra time. Therefore, f2fs_update_meta_pages and
* sync_meta_pages are combined in this function. * f2fs_sync_meta_pages are combined in this function.
*/ */
struct page *page = grab_meta_page(sbi, blk_addr); struct page *page = f2fs_grab_meta_page(sbi, blk_addr);
int err; int err;
memcpy(page_address(page), src, PAGE_SIZE); memcpy(page_address(page), src, PAGE_SIZE);
...@@ -1220,7 +1226,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) ...@@ -1220,7 +1226,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
/* Flush all the NAT/SIT pages */ /* Flush all the NAT/SIT pages */
while (get_pages(sbi, F2FS_DIRTY_META)) { while (get_pages(sbi, F2FS_DIRTY_META)) {
sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO); f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO);
if (unlikely(f2fs_cp_error(sbi))) if (unlikely(f2fs_cp_error(sbi)))
return -EIO; return -EIO;
} }
...@@ -1229,7 +1235,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) ...@@ -1229,7 +1235,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
* modify checkpoint * modify checkpoint
* version number is already updated * version number is already updated
*/ */
ckpt->elapsed_time = cpu_to_le64(get_mtime(sbi)); ckpt->elapsed_time = cpu_to_le64(get_mtime(sbi, true));
ckpt->free_segment_count = cpu_to_le32(free_segments(sbi)); ckpt->free_segment_count = cpu_to_le32(free_segments(sbi));
for (i = 0; i < NR_CURSEG_NODE_TYPE; i++) { for (i = 0; i < NR_CURSEG_NODE_TYPE; i++) {
ckpt->cur_node_segno[i] = ckpt->cur_node_segno[i] =
...@@ -1249,7 +1255,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) ...@@ -1249,7 +1255,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
} }
/* 2 cp + n data seg summary + orphan inode blocks */ /* 2 cp + n data seg summary + orphan inode blocks */
data_sum_blocks = npages_for_summary_flush(sbi, false); data_sum_blocks = f2fs_npages_for_summary_flush(sbi, false);
spin_lock_irqsave(&sbi->cp_lock, flags); spin_lock_irqsave(&sbi->cp_lock, flags);
if (data_sum_blocks < NR_CURSEG_DATA_TYPE) if (data_sum_blocks < NR_CURSEG_DATA_TYPE)
__set_ckpt_flags(ckpt, CP_COMPACT_SUM_FLAG); __set_ckpt_flags(ckpt, CP_COMPACT_SUM_FLAG);
...@@ -1294,22 +1300,23 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) ...@@ -1294,22 +1300,23 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
blk = start_blk + sbi->blocks_per_seg - nm_i->nat_bits_blocks; blk = start_blk + sbi->blocks_per_seg - nm_i->nat_bits_blocks;
for (i = 0; i < nm_i->nat_bits_blocks; i++) for (i = 0; i < nm_i->nat_bits_blocks; i++)
update_meta_page(sbi, nm_i->nat_bits + f2fs_update_meta_page(sbi, nm_i->nat_bits +
(i << F2FS_BLKSIZE_BITS), blk + i); (i << F2FS_BLKSIZE_BITS), blk + i);
/* Flush all the NAT BITS pages */ /* Flush all the NAT BITS pages */
while (get_pages(sbi, F2FS_DIRTY_META)) { while (get_pages(sbi, F2FS_DIRTY_META)) {
sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO); f2fs_sync_meta_pages(sbi, META, LONG_MAX,
FS_CP_META_IO);
if (unlikely(f2fs_cp_error(sbi))) if (unlikely(f2fs_cp_error(sbi)))
return -EIO; return -EIO;
} }
} }
/* write out checkpoint buffer at block 0 */ /* write out checkpoint buffer at block 0 */
update_meta_page(sbi, ckpt, start_blk++); f2fs_update_meta_page(sbi, ckpt, start_blk++);
for (i = 1; i < 1 + cp_payload_blks; i++) for (i = 1; i < 1 + cp_payload_blks; i++)
update_meta_page(sbi, (char *)ckpt + i * F2FS_BLKSIZE, f2fs_update_meta_page(sbi, (char *)ckpt + i * F2FS_BLKSIZE,
start_blk++); start_blk++);
if (orphan_num) { if (orphan_num) {
...@@ -1317,7 +1324,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) ...@@ -1317,7 +1324,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
start_blk += orphan_blocks; start_blk += orphan_blocks;
} }
write_data_summaries(sbi, start_blk); f2fs_write_data_summaries(sbi, start_blk);
start_blk += data_sum_blocks; start_blk += data_sum_blocks;
/* Record write statistics in the hot node summary */ /* Record write statistics in the hot node summary */
...@@ -1328,7 +1335,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) ...@@ -1328,7 +1335,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
seg_i->journal->info.kbytes_written = cpu_to_le64(kbytes_written); seg_i->journal->info.kbytes_written = cpu_to_le64(kbytes_written);
if (__remain_node_summaries(cpc->reason)) { if (__remain_node_summaries(cpc->reason)) {
write_node_summaries(sbi, start_blk); f2fs_write_node_summaries(sbi, start_blk);
start_blk += NR_CURSEG_NODE_TYPE; start_blk += NR_CURSEG_NODE_TYPE;
} }
...@@ -1337,7 +1344,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) ...@@ -1337,7 +1344,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
percpu_counter_set(&sbi->alloc_valid_block_count, 0); percpu_counter_set(&sbi->alloc_valid_block_count, 0);
/* Here, we have one bio having CP pack except cp pack 2 page */ /* Here, we have one bio having CP pack except cp pack 2 page */
sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO); f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO);
/* wait for previous submitted meta pages writeback */ /* wait for previous submitted meta pages writeback */
wait_on_all_pages_writeback(sbi); wait_on_all_pages_writeback(sbi);
...@@ -1354,7 +1361,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) ...@@ -1354,7 +1361,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
commit_checkpoint(sbi, ckpt, start_blk); commit_checkpoint(sbi, ckpt, start_blk);
wait_on_all_pages_writeback(sbi); wait_on_all_pages_writeback(sbi);
release_ino_entry(sbi, false); f2fs_release_ino_entry(sbi, false);
if (unlikely(f2fs_cp_error(sbi))) if (unlikely(f2fs_cp_error(sbi)))
return -EIO; return -EIO;
...@@ -1379,7 +1386,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) ...@@ -1379,7 +1386,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
/* /*
* We guarantee that this checkpoint procedure will not fail. * We guarantee that this checkpoint procedure will not fail.
*/ */
int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
{ {
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
unsigned long long ckpt_ver; unsigned long long ckpt_ver;
...@@ -1412,7 +1419,7 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) ...@@ -1412,7 +1419,7 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
/* this is the case of multiple fstrims without any changes */ /* this is the case of multiple fstrims without any changes */
if (cpc->reason & CP_DISCARD) { if (cpc->reason & CP_DISCARD) {
if (!exist_trim_candidates(sbi, cpc)) { if (!f2fs_exist_trim_candidates(sbi, cpc)) {
unblock_operations(sbi); unblock_operations(sbi);
goto out; goto out;
} }
...@@ -1420,8 +1427,8 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) ...@@ -1420,8 +1427,8 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
if (NM_I(sbi)->dirty_nat_cnt == 0 && if (NM_I(sbi)->dirty_nat_cnt == 0 &&
SIT_I(sbi)->dirty_sentries == 0 && SIT_I(sbi)->dirty_sentries == 0 &&
prefree_segments(sbi) == 0) { prefree_segments(sbi) == 0) {
flush_sit_entries(sbi, cpc); f2fs_flush_sit_entries(sbi, cpc);
clear_prefree_segments(sbi, cpc); f2fs_clear_prefree_segments(sbi, cpc);
unblock_operations(sbi); unblock_operations(sbi);
goto out; goto out;
} }
...@@ -1436,15 +1443,15 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) ...@@ -1436,15 +1443,15 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
ckpt->checkpoint_ver = cpu_to_le64(++ckpt_ver); ckpt->checkpoint_ver = cpu_to_le64(++ckpt_ver);
/* write cached NAT/SIT entries to NAT/SIT area */ /* write cached NAT/SIT entries to NAT/SIT area */
flush_nat_entries(sbi, cpc); f2fs_flush_nat_entries(sbi, cpc);
flush_sit_entries(sbi, cpc); f2fs_flush_sit_entries(sbi, cpc);
/* unlock all the fs_lock[] in do_checkpoint() */ /* unlock all the fs_lock[] in do_checkpoint() */
err = do_checkpoint(sbi, cpc); err = do_checkpoint(sbi, cpc);
if (err) if (err)
release_discard_addrs(sbi); f2fs_release_discard_addrs(sbi);
else else
clear_prefree_segments(sbi, cpc); f2fs_clear_prefree_segments(sbi, cpc);
unblock_operations(sbi); unblock_operations(sbi);
stat_inc_cp_count(sbi->stat_info); stat_inc_cp_count(sbi->stat_info);
...@@ -1461,7 +1468,7 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) ...@@ -1461,7 +1468,7 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
return err; return err;
} }
void init_ino_entry_info(struct f2fs_sb_info *sbi) void f2fs_init_ino_entry_info(struct f2fs_sb_info *sbi)
{ {
int i; int i;
...@@ -1479,23 +1486,23 @@ void init_ino_entry_info(struct f2fs_sb_info *sbi) ...@@ -1479,23 +1486,23 @@ void init_ino_entry_info(struct f2fs_sb_info *sbi)
F2FS_ORPHANS_PER_BLOCK; F2FS_ORPHANS_PER_BLOCK;
} }
int __init create_checkpoint_caches(void) int __init f2fs_create_checkpoint_caches(void)
{ {
ino_entry_slab = f2fs_kmem_cache_create("f2fs_ino_entry", ino_entry_slab = f2fs_kmem_cache_create("f2fs_ino_entry",
sizeof(struct ino_entry)); sizeof(struct ino_entry));
if (!ino_entry_slab) if (!ino_entry_slab)
return -ENOMEM; return -ENOMEM;
inode_entry_slab = f2fs_kmem_cache_create("f2fs_inode_entry", f2fs_inode_entry_slab = f2fs_kmem_cache_create("f2fs_inode_entry",
sizeof(struct inode_entry)); sizeof(struct inode_entry));
if (!inode_entry_slab) { if (!f2fs_inode_entry_slab) {
kmem_cache_destroy(ino_entry_slab); kmem_cache_destroy(ino_entry_slab);
return -ENOMEM; return -ENOMEM;
} }
return 0; return 0;
} }
void destroy_checkpoint_caches(void) void f2fs_destroy_checkpoint_caches(void)
{ {
kmem_cache_destroy(ino_entry_slab); kmem_cache_destroy(ino_entry_slab);
kmem_cache_destroy(inode_entry_slab); kmem_cache_destroy(f2fs_inode_entry_slab);
} }
此差异已折叠。
...@@ -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,
......
...@@ -60,12 +60,12 @@ static unsigned char f2fs_type_by_mode[S_IFMT >> S_SHIFT] = { ...@@ -60,12 +60,12 @@ static unsigned char f2fs_type_by_mode[S_IFMT >> S_SHIFT] = {
[S_IFLNK >> S_SHIFT] = F2FS_FT_SYMLINK, [S_IFLNK >> S_SHIFT] = F2FS_FT_SYMLINK,
}; };
void set_de_type(struct f2fs_dir_entry *de, umode_t mode) static void set_de_type(struct f2fs_dir_entry *de, umode_t mode)
{ {
de->file_type = f2fs_type_by_mode[(mode & S_IFMT) >> S_SHIFT]; de->file_type = f2fs_type_by_mode[(mode & S_IFMT) >> S_SHIFT];
} }
unsigned char get_de_type(struct f2fs_dir_entry *de) unsigned char f2fs_get_de_type(struct f2fs_dir_entry *de)
{ {
if (de->file_type < F2FS_FT_MAX) if (de->file_type < F2FS_FT_MAX)
return f2fs_filetype_table[de->file_type]; return f2fs_filetype_table[de->file_type];
...@@ -97,14 +97,14 @@ static struct f2fs_dir_entry *find_in_block(struct page *dentry_page, ...@@ -97,14 +97,14 @@ static struct f2fs_dir_entry *find_in_block(struct page *dentry_page,
dentry_blk = (struct f2fs_dentry_block *)page_address(dentry_page); dentry_blk = (struct f2fs_dentry_block *)page_address(dentry_page);
make_dentry_ptr_block(NULL, &d, dentry_blk); make_dentry_ptr_block(NULL, &d, dentry_blk);
de = find_target_dentry(fname, namehash, max_slots, &d); de = f2fs_find_target_dentry(fname, namehash, max_slots, &d);
if (de) if (de)
*res_page = dentry_page; *res_page = dentry_page;
return de; return de;
} }
struct f2fs_dir_entry *find_target_dentry(struct fscrypt_name *fname, struct f2fs_dir_entry *f2fs_find_target_dentry(struct fscrypt_name *fname,
f2fs_hash_t namehash, int *max_slots, f2fs_hash_t namehash, int *max_slots,
struct f2fs_dentry_ptr *d) struct f2fs_dentry_ptr *d)
{ {
...@@ -171,7 +171,7 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir, ...@@ -171,7 +171,7 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir,
for (; bidx < end_block; bidx++) { for (; bidx < end_block; bidx++) {
/* no need to allocate new dentry pages to all the indices */ /* no need to allocate new dentry pages to all the indices */
dentry_page = find_data_page(dir, bidx); dentry_page = f2fs_find_data_page(dir, bidx);
if (IS_ERR(dentry_page)) { if (IS_ERR(dentry_page)) {
if (PTR_ERR(dentry_page) == -ENOENT) { if (PTR_ERR(dentry_page) == -ENOENT) {
room = true; room = true;
...@@ -210,7 +210,7 @@ struct f2fs_dir_entry *__f2fs_find_entry(struct inode *dir, ...@@ -210,7 +210,7 @@ struct f2fs_dir_entry *__f2fs_find_entry(struct inode *dir,
if (f2fs_has_inline_dentry(dir)) { if (f2fs_has_inline_dentry(dir)) {
*res_page = NULL; *res_page = NULL;
de = find_in_inline_dir(dir, fname, res_page); de = f2fs_find_in_inline_dir(dir, fname, res_page);
goto out; goto out;
} }
...@@ -319,7 +319,7 @@ static void init_dent_inode(const struct qstr *name, struct page *ipage) ...@@ -319,7 +319,7 @@ static void init_dent_inode(const struct qstr *name, struct page *ipage)
set_page_dirty(ipage); set_page_dirty(ipage);
} }
void do_make_empty_dir(struct inode *inode, struct inode *parent, void f2fs_do_make_empty_dir(struct inode *inode, struct inode *parent,
struct f2fs_dentry_ptr *d) struct f2fs_dentry_ptr *d)
{ {
struct qstr dot = QSTR_INIT(".", 1); struct qstr dot = QSTR_INIT(".", 1);
...@@ -340,23 +340,23 @@ static int make_empty_dir(struct inode *inode, ...@@ -340,23 +340,23 @@ static int make_empty_dir(struct inode *inode,
struct f2fs_dentry_ptr d; struct f2fs_dentry_ptr d;
if (f2fs_has_inline_dentry(inode)) if (f2fs_has_inline_dentry(inode))
return make_empty_inline_dir(inode, parent, page); return f2fs_make_empty_inline_dir(inode, parent, page);
dentry_page = get_new_data_page(inode, page, 0, true); dentry_page = f2fs_get_new_data_page(inode, page, 0, true);
if (IS_ERR(dentry_page)) if (IS_ERR(dentry_page))
return PTR_ERR(dentry_page); return PTR_ERR(dentry_page);
dentry_blk = page_address(dentry_page); dentry_blk = page_address(dentry_page);
make_dentry_ptr_block(NULL, &d, dentry_blk); make_dentry_ptr_block(NULL, &d, dentry_blk);
do_make_empty_dir(inode, parent, &d); f2fs_do_make_empty_dir(inode, parent, &d);
set_page_dirty(dentry_page); set_page_dirty(dentry_page);
f2fs_put_page(dentry_page, 1); f2fs_put_page(dentry_page, 1);
return 0; return 0;
} }
struct page *init_inode_metadata(struct inode *inode, struct inode *dir, struct page *f2fs_init_inode_metadata(struct inode *inode, struct inode *dir,
const struct qstr *new_name, const struct qstr *orig_name, const struct qstr *new_name, const struct qstr *orig_name,
struct page *dpage) struct page *dpage)
{ {
...@@ -365,7 +365,7 @@ struct page *init_inode_metadata(struct inode *inode, struct inode *dir, ...@@ -365,7 +365,7 @@ struct page *init_inode_metadata(struct inode *inode, struct inode *dir,
int err; int err;
if (is_inode_flag_set(inode, FI_NEW_INODE)) { if (is_inode_flag_set(inode, FI_NEW_INODE)) {
page = new_inode_page(inode); page = f2fs_new_inode_page(inode);
if (IS_ERR(page)) if (IS_ERR(page))
return page; return page;
...@@ -395,7 +395,7 @@ struct page *init_inode_metadata(struct inode *inode, struct inode *dir, ...@@ -395,7 +395,7 @@ struct page *init_inode_metadata(struct inode *inode, struct inode *dir,
goto put_error; goto put_error;
} }
} else { } else {
page = get_node_page(F2FS_I_SB(dir), inode->i_ino); page = f2fs_get_node_page(F2FS_I_SB(dir), inode->i_ino);
if (IS_ERR(page)) if (IS_ERR(page))
return page; return page;
} }
...@@ -418,19 +418,19 @@ struct page *init_inode_metadata(struct inode *inode, struct inode *dir, ...@@ -418,19 +418,19 @@ struct page *init_inode_metadata(struct inode *inode, struct inode *dir,
* we should remove this inode from orphan list. * we should remove this inode from orphan list.
*/ */
if (inode->i_nlink == 0) if (inode->i_nlink == 0)
remove_orphan_inode(F2FS_I_SB(dir), inode->i_ino); f2fs_remove_orphan_inode(F2FS_I_SB(dir), inode->i_ino);
f2fs_i_links_write(inode, true); f2fs_i_links_write(inode, true);
} }
return page; return page;
put_error: put_error:
clear_nlink(inode); clear_nlink(inode);
update_inode(inode, page); f2fs_update_inode(inode, page);
f2fs_put_page(page, 1); f2fs_put_page(page, 1);
return ERR_PTR(err); return ERR_PTR(err);
} }
void update_parent_metadata(struct inode *dir, struct inode *inode, void f2fs_update_parent_metadata(struct inode *dir, struct inode *inode,
unsigned int current_depth) unsigned int current_depth)
{ {
if (inode && is_inode_flag_set(inode, FI_NEW_INODE)) { if (inode && is_inode_flag_set(inode, FI_NEW_INODE)) {
...@@ -448,7 +448,7 @@ void update_parent_metadata(struct inode *dir, struct inode *inode, ...@@ -448,7 +448,7 @@ void update_parent_metadata(struct inode *dir, struct inode *inode,
clear_inode_flag(inode, FI_INC_LINK); clear_inode_flag(inode, FI_INC_LINK);
} }
int room_for_filename(const void *bitmap, int slots, int max_slots) int f2fs_room_for_filename(const void *bitmap, int slots, int max_slots)
{ {
int bit_start = 0; int bit_start = 0;
int zero_start, zero_end; int zero_start, zero_end;
...@@ -537,12 +537,12 @@ int f2fs_add_regular_entry(struct inode *dir, const struct qstr *new_name, ...@@ -537,12 +537,12 @@ int f2fs_add_regular_entry(struct inode *dir, const struct qstr *new_name,
(le32_to_cpu(dentry_hash) % nbucket)); (le32_to_cpu(dentry_hash) % nbucket));
for (block = bidx; block <= (bidx + nblock - 1); block++) { for (block = bidx; block <= (bidx + nblock - 1); block++) {
dentry_page = get_new_data_page(dir, NULL, block, true); dentry_page = f2fs_get_new_data_page(dir, NULL, block, true);
if (IS_ERR(dentry_page)) if (IS_ERR(dentry_page))
return PTR_ERR(dentry_page); return PTR_ERR(dentry_page);
dentry_blk = page_address(dentry_page); dentry_blk = page_address(dentry_page);
bit_pos = room_for_filename(&dentry_blk->dentry_bitmap, bit_pos = f2fs_room_for_filename(&dentry_blk->dentry_bitmap,
slots, NR_DENTRY_IN_BLOCK); slots, NR_DENTRY_IN_BLOCK);
if (bit_pos < NR_DENTRY_IN_BLOCK) if (bit_pos < NR_DENTRY_IN_BLOCK)
goto add_dentry; goto add_dentry;
...@@ -558,7 +558,7 @@ int f2fs_add_regular_entry(struct inode *dir, const struct qstr *new_name, ...@@ -558,7 +558,7 @@ int f2fs_add_regular_entry(struct inode *dir, const struct qstr *new_name,
if (inode) { if (inode) {
down_write(&F2FS_I(inode)->i_sem); down_write(&F2FS_I(inode)->i_sem);
page = init_inode_metadata(inode, dir, new_name, page = f2fs_init_inode_metadata(inode, dir, new_name,
orig_name, NULL); orig_name, NULL);
if (IS_ERR(page)) { if (IS_ERR(page)) {
err = PTR_ERR(page); err = PTR_ERR(page);
...@@ -576,7 +576,7 @@ int f2fs_add_regular_entry(struct inode *dir, const struct qstr *new_name, ...@@ -576,7 +576,7 @@ int f2fs_add_regular_entry(struct inode *dir, const struct qstr *new_name,
f2fs_put_page(page, 1); f2fs_put_page(page, 1);
} }
update_parent_metadata(dir, inode, current_depth); f2fs_update_parent_metadata(dir, inode, current_depth);
fail: fail:
if (inode) if (inode)
up_write(&F2FS_I(inode)->i_sem); up_write(&F2FS_I(inode)->i_sem);
...@@ -586,7 +586,7 @@ int f2fs_add_regular_entry(struct inode *dir, const struct qstr *new_name, ...@@ -586,7 +586,7 @@ int f2fs_add_regular_entry(struct inode *dir, const struct qstr *new_name,
return err; return err;
} }
int __f2fs_do_add_link(struct inode *dir, struct fscrypt_name *fname, int f2fs_add_dentry(struct inode *dir, struct fscrypt_name *fname,
struct inode *inode, nid_t ino, umode_t mode) struct inode *inode, nid_t ino, umode_t mode)
{ {
struct qstr new_name; struct qstr new_name;
...@@ -610,7 +610,7 @@ int __f2fs_do_add_link(struct inode *dir, struct fscrypt_name *fname, ...@@ -610,7 +610,7 @@ int __f2fs_do_add_link(struct inode *dir, struct fscrypt_name *fname,
* Caller should grab and release a rwsem by calling f2fs_lock_op() and * Caller should grab and release a rwsem by calling f2fs_lock_op() and
* f2fs_unlock_op(). * f2fs_unlock_op().
*/ */
int __f2fs_add_link(struct inode *dir, const struct qstr *name, int f2fs_do_add_link(struct inode *dir, const struct qstr *name,
struct inode *inode, nid_t ino, umode_t mode) struct inode *inode, nid_t ino, umode_t mode)
{ {
struct fscrypt_name fname; struct fscrypt_name fname;
...@@ -639,7 +639,7 @@ int __f2fs_add_link(struct inode *dir, const struct qstr *name, ...@@ -639,7 +639,7 @@ int __f2fs_add_link(struct inode *dir, const struct qstr *name,
} else if (IS_ERR(page)) { } else if (IS_ERR(page)) {
err = PTR_ERR(page); err = PTR_ERR(page);
} else { } else {
err = __f2fs_do_add_link(dir, &fname, inode, ino, mode); err = f2fs_add_dentry(dir, &fname, inode, ino, mode);
} }
fscrypt_free_filename(&fname); fscrypt_free_filename(&fname);
return err; return err;
...@@ -651,7 +651,7 @@ int f2fs_do_tmpfile(struct inode *inode, struct inode *dir) ...@@ -651,7 +651,7 @@ int f2fs_do_tmpfile(struct inode *inode, struct inode *dir)
int err = 0; int err = 0;
down_write(&F2FS_I(inode)->i_sem); down_write(&F2FS_I(inode)->i_sem);
page = init_inode_metadata(inode, dir, NULL, NULL, NULL); page = f2fs_init_inode_metadata(inode, dir, NULL, NULL, NULL);
if (IS_ERR(page)) { if (IS_ERR(page)) {
err = PTR_ERR(page); err = PTR_ERR(page);
goto fail; goto fail;
...@@ -683,9 +683,9 @@ void f2fs_drop_nlink(struct inode *dir, struct inode *inode) ...@@ -683,9 +683,9 @@ void f2fs_drop_nlink(struct inode *dir, struct inode *inode)
up_write(&F2FS_I(inode)->i_sem); up_write(&F2FS_I(inode)->i_sem);
if (inode->i_nlink == 0) if (inode->i_nlink == 0)
add_orphan_inode(inode); f2fs_add_orphan_inode(inode);
else else
release_orphan_inode(sbi); f2fs_release_orphan_inode(sbi);
} }
/* /*
...@@ -698,14 +698,12 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, ...@@ -698,14 +698,12 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
struct f2fs_dentry_block *dentry_blk; struct f2fs_dentry_block *dentry_blk;
unsigned int bit_pos; unsigned int bit_pos;
int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len)); int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len));
struct address_space *mapping = page_mapping(page);
unsigned long flags;
int i; int i;
f2fs_update_time(F2FS_I_SB(dir), REQ_TIME); f2fs_update_time(F2FS_I_SB(dir), REQ_TIME);
if (F2FS_OPTION(F2FS_I_SB(dir)).fsync_mode == FSYNC_MODE_STRICT) if (F2FS_OPTION(F2FS_I_SB(dir)).fsync_mode == FSYNC_MODE_STRICT)
add_ino_entry(F2FS_I_SB(dir), dir->i_ino, TRANS_DIR_INO); f2fs_add_ino_entry(F2FS_I_SB(dir), dir->i_ino, TRANS_DIR_INO);
if (f2fs_has_inline_dentry(dir)) if (f2fs_has_inline_dentry(dir))
return f2fs_delete_inline_entry(dentry, page, dir, inode); return f2fs_delete_inline_entry(dentry, page, dir, inode);
...@@ -731,17 +729,13 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, ...@@ -731,17 +729,13 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
f2fs_drop_nlink(dir, inode); f2fs_drop_nlink(dir, inode);
if (bit_pos == NR_DENTRY_IN_BLOCK && if (bit_pos == NR_DENTRY_IN_BLOCK &&
!truncate_hole(dir, page->index, page->index + 1)) { !f2fs_truncate_hole(dir, page->index, page->index + 1)) {
xa_lock_irqsave(&mapping->i_pages, flags); f2fs_clear_radix_tree_dirty_tag(page);
radix_tree_tag_clear(&mapping->i_pages, page_index(page),
PAGECACHE_TAG_DIRTY);
xa_unlock_irqrestore(&mapping->i_pages, flags);
clear_page_dirty_for_io(page); clear_page_dirty_for_io(page);
ClearPagePrivate(page); ClearPagePrivate(page);
ClearPageUptodate(page); ClearPageUptodate(page);
inode_dec_dirty_pages(dir); inode_dec_dirty_pages(dir);
remove_dirty_inode(dir); f2fs_remove_dirty_inode(dir);
} }
f2fs_put_page(page, 1); f2fs_put_page(page, 1);
} }
...@@ -758,7 +752,7 @@ bool f2fs_empty_dir(struct inode *dir) ...@@ -758,7 +752,7 @@ bool f2fs_empty_dir(struct inode *dir)
return f2fs_empty_inline_dir(dir); return f2fs_empty_inline_dir(dir);
for (bidx = 0; bidx < nblock; bidx++) { for (bidx = 0; bidx < nblock; bidx++) {
dentry_page = get_lock_data_page(dir, bidx, false); dentry_page = f2fs_get_lock_data_page(dir, bidx, false);
if (IS_ERR(dentry_page)) { if (IS_ERR(dentry_page)) {
if (PTR_ERR(dentry_page) == -ENOENT) if (PTR_ERR(dentry_page) == -ENOENT)
continue; continue;
...@@ -806,7 +800,7 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, ...@@ -806,7 +800,7 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
continue; continue;
} }
d_type = get_de_type(de); d_type = f2fs_get_de_type(de);
de_name.name = d->filename[bit_pos]; de_name.name = d->filename[bit_pos];
de_name.len = le16_to_cpu(de->name_len); de_name.len = le16_to_cpu(de->name_len);
...@@ -830,7 +824,7 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, ...@@ -830,7 +824,7 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
return 1; return 1;
if (sbi->readdir_ra == 1) if (sbi->readdir_ra == 1)
ra_node_page(sbi, le32_to_cpu(de->ino)); f2fs_ra_node_page(sbi, le32_to_cpu(de->ino));
bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
ctx->pos = start_pos + bit_pos; ctx->pos = start_pos + bit_pos;
...@@ -880,7 +874,7 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx) ...@@ -880,7 +874,7 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
page_cache_sync_readahead(inode->i_mapping, ra, file, n, page_cache_sync_readahead(inode->i_mapping, ra, file, n,
min(npages - n, (pgoff_t)MAX_DIR_RA_PAGES)); min(npages - n, (pgoff_t)MAX_DIR_RA_PAGES));
dentry_page = get_lock_data_page(inode, n, false); dentry_page = f2fs_get_lock_data_page(inode, n, false);
if (IS_ERR(dentry_page)) { if (IS_ERR(dentry_page)) {
err = PTR_ERR(dentry_page); err = PTR_ERR(dentry_page);
if (err == -ENOENT) { if (err == -ENOENT) {
......
...@@ -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);
......
此差异已折叠。
此差异已折叠。
...@@ -76,7 +76,7 @@ static int gc_thread_func(void *data) ...@@ -76,7 +76,7 @@ static int gc_thread_func(void *data)
* invalidated soon after by user update or deletion. * invalidated soon after by user update or deletion.
* So, I'd like to wait some time to collect dirty segments. * So, I'd like to wait some time to collect dirty segments.
*/ */
if (gc_th->gc_urgent) { if (sbi->gc_mode == GC_URGENT) {
wait_ms = gc_th->urgent_sleep_time; wait_ms = gc_th->urgent_sleep_time;
mutex_lock(&sbi->gc_mutex); mutex_lock(&sbi->gc_mutex);
goto do_gc; goto do_gc;
...@@ -114,7 +114,7 @@ static int gc_thread_func(void *data) ...@@ -114,7 +114,7 @@ static int gc_thread_func(void *data)
return 0; return 0;
} }
int start_gc_thread(struct f2fs_sb_info *sbi) int f2fs_start_gc_thread(struct f2fs_sb_info *sbi)
{ {
struct f2fs_gc_kthread *gc_th; struct f2fs_gc_kthread *gc_th;
dev_t dev = sbi->sb->s_bdev->bd_dev; dev_t dev = sbi->sb->s_bdev->bd_dev;
...@@ -131,8 +131,6 @@ int start_gc_thread(struct f2fs_sb_info *sbi) ...@@ -131,8 +131,6 @@ int start_gc_thread(struct f2fs_sb_info *sbi)
gc_th->max_sleep_time = DEF_GC_THREAD_MAX_SLEEP_TIME; gc_th->max_sleep_time = DEF_GC_THREAD_MAX_SLEEP_TIME;
gc_th->no_gc_sleep_time = DEF_GC_THREAD_NOGC_SLEEP_TIME; gc_th->no_gc_sleep_time = DEF_GC_THREAD_NOGC_SLEEP_TIME;
gc_th->gc_idle = 0;
gc_th->gc_urgent = 0;
gc_th->gc_wake= 0; gc_th->gc_wake= 0;
sbi->gc_thread = gc_th; sbi->gc_thread = gc_th;
...@@ -148,7 +146,7 @@ int start_gc_thread(struct f2fs_sb_info *sbi) ...@@ -148,7 +146,7 @@ int start_gc_thread(struct f2fs_sb_info *sbi)
return err; return err;
} }
void stop_gc_thread(struct f2fs_sb_info *sbi) void f2fs_stop_gc_thread(struct f2fs_sb_info *sbi)
{ {
struct f2fs_gc_kthread *gc_th = sbi->gc_thread; struct f2fs_gc_kthread *gc_th = sbi->gc_thread;
if (!gc_th) if (!gc_th)
...@@ -158,21 +156,19 @@ void stop_gc_thread(struct f2fs_sb_info *sbi) ...@@ -158,21 +156,19 @@ void stop_gc_thread(struct f2fs_sb_info *sbi)
sbi->gc_thread = NULL; sbi->gc_thread = NULL;
} }
static int select_gc_type(struct f2fs_gc_kthread *gc_th, int gc_type) static int select_gc_type(struct f2fs_sb_info *sbi, int gc_type)
{ {
int gc_mode = (gc_type == BG_GC) ? GC_CB : GC_GREEDY; int gc_mode = (gc_type == BG_GC) ? GC_CB : GC_GREEDY;
if (!gc_th) switch (sbi->gc_mode) {
return gc_mode; case GC_IDLE_CB:
gc_mode = GC_CB;
if (gc_th->gc_idle) { break;
if (gc_th->gc_idle == 1) case GC_IDLE_GREEDY:
gc_mode = GC_CB; case GC_URGENT:
else if (gc_th->gc_idle == 2)
gc_mode = GC_GREEDY;
}
if (gc_th->gc_urgent)
gc_mode = GC_GREEDY; gc_mode = GC_GREEDY;
break;
}
return gc_mode; return gc_mode;
} }
...@@ -187,7 +183,7 @@ static void select_policy(struct f2fs_sb_info *sbi, int gc_type, ...@@ -187,7 +183,7 @@ static void select_policy(struct f2fs_sb_info *sbi, int gc_type,
p->max_search = dirty_i->nr_dirty[type]; p->max_search = dirty_i->nr_dirty[type];
p->ofs_unit = 1; p->ofs_unit = 1;
} else { } else {
p->gc_mode = select_gc_type(sbi->gc_thread, gc_type); p->gc_mode = select_gc_type(sbi, gc_type);
p->dirty_segmap = dirty_i->dirty_segmap[DIRTY]; p->dirty_segmap = dirty_i->dirty_segmap[DIRTY];
p->max_search = dirty_i->nr_dirty[DIRTY]; p->max_search = dirty_i->nr_dirty[DIRTY];
p->ofs_unit = sbi->segs_per_sec; p->ofs_unit = sbi->segs_per_sec;
...@@ -195,7 +191,7 @@ static void select_policy(struct f2fs_sb_info *sbi, int gc_type, ...@@ -195,7 +191,7 @@ static void select_policy(struct f2fs_sb_info *sbi, int gc_type,
/* we need to check every dirty segments in the FG_GC case */ /* we need to check every dirty segments in the FG_GC case */
if (gc_type != FG_GC && if (gc_type != FG_GC &&
(sbi->gc_thread && !sbi->gc_thread->gc_urgent) && (sbi->gc_mode != GC_URGENT) &&
p->max_search > sbi->max_victim_search) p->max_search > sbi->max_victim_search)
p->max_search = sbi->max_victim_search; p->max_search = sbi->max_victim_search;
...@@ -234,10 +230,6 @@ static unsigned int check_bg_victims(struct f2fs_sb_info *sbi) ...@@ -234,10 +230,6 @@ static unsigned int check_bg_victims(struct f2fs_sb_info *sbi)
for_each_set_bit(secno, dirty_i->victim_secmap, MAIN_SECS(sbi)) { for_each_set_bit(secno, dirty_i->victim_secmap, MAIN_SECS(sbi)) {
if (sec_usage_check(sbi, secno)) if (sec_usage_check(sbi, secno))
continue; continue;
if (no_fggc_candidate(sbi, secno))
continue;
clear_bit(secno, dirty_i->victim_secmap); clear_bit(secno, dirty_i->victim_secmap);
return GET_SEG_FROM_SEC(sbi, secno); return GET_SEG_FROM_SEC(sbi, secno);
} }
...@@ -377,9 +369,6 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi, ...@@ -377,9 +369,6 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
goto next; goto next;
if (gc_type == BG_GC && test_bit(secno, dirty_i->victim_secmap)) if (gc_type == BG_GC && test_bit(secno, dirty_i->victim_secmap))
goto next; goto next;
if (gc_type == FG_GC && p.alloc_mode == LFS &&
no_fggc_candidate(sbi, secno))
goto next;
cost = get_gc_cost(sbi, segno, &p); cost = get_gc_cost(sbi, segno, &p);
...@@ -440,7 +429,7 @@ static void add_gc_inode(struct gc_inode_list *gc_list, struct inode *inode) ...@@ -440,7 +429,7 @@ static void add_gc_inode(struct gc_inode_list *gc_list, struct inode *inode)
iput(inode); iput(inode);
return; return;
} }
new_ie = f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS); new_ie = f2fs_kmem_cache_alloc(f2fs_inode_entry_slab, GFP_NOFS);
new_ie->inode = inode; new_ie->inode = inode;
f2fs_radix_tree_insert(&gc_list->iroot, inode->i_ino, new_ie); f2fs_radix_tree_insert(&gc_list->iroot, inode->i_ino, new_ie);
...@@ -454,7 +443,7 @@ static void put_gc_inode(struct gc_inode_list *gc_list) ...@@ -454,7 +443,7 @@ static void put_gc_inode(struct gc_inode_list *gc_list)
radix_tree_delete(&gc_list->iroot, ie->inode->i_ino); radix_tree_delete(&gc_list->iroot, ie->inode->i_ino);
iput(ie->inode); iput(ie->inode);
list_del(&ie->list); list_del(&ie->list);
kmem_cache_free(inode_entry_slab, ie); kmem_cache_free(f2fs_inode_entry_slab, ie);
} }
} }
...@@ -484,12 +473,16 @@ static void gc_node_segment(struct f2fs_sb_info *sbi, ...@@ -484,12 +473,16 @@ static void gc_node_segment(struct f2fs_sb_info *sbi,
block_t start_addr; block_t start_addr;
int off; int off;
int phase = 0; int phase = 0;
bool fggc = (gc_type == FG_GC);
start_addr = START_BLOCK(sbi, segno); start_addr = START_BLOCK(sbi, segno);
next_step: next_step:
entry = sum; entry = sum;
if (fggc && phase == 2)
atomic_inc(&sbi->wb_sync_req[NODE]);
for (off = 0; off < sbi->blocks_per_seg; off++, entry++) { for (off = 0; off < sbi->blocks_per_seg; off++, entry++) {
nid_t nid = le32_to_cpu(entry->nid); nid_t nid = le32_to_cpu(entry->nid);
struct page *node_page; struct page *node_page;
...@@ -503,39 +496,42 @@ static void gc_node_segment(struct f2fs_sb_info *sbi, ...@@ -503,39 +496,42 @@ static void gc_node_segment(struct f2fs_sb_info *sbi,
continue; continue;
if (phase == 0) { if (phase == 0) {
ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), 1, f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), 1,
META_NAT, true); META_NAT, true);
continue; continue;
} }
if (phase == 1) { if (phase == 1) {
ra_node_page(sbi, nid); f2fs_ra_node_page(sbi, nid);
continue; continue;
} }
/* phase == 2 */ /* phase == 2 */
node_page = get_node_page(sbi, nid); node_page = f2fs_get_node_page(sbi, nid);
if (IS_ERR(node_page)) if (IS_ERR(node_page))
continue; continue;
/* block may become invalid during get_node_page */ /* block may become invalid during f2fs_get_node_page */
if (check_valid_map(sbi, segno, off) == 0) { if (check_valid_map(sbi, segno, off) == 0) {
f2fs_put_page(node_page, 1); f2fs_put_page(node_page, 1);
continue; continue;
} }
get_node_info(sbi, nid, &ni); f2fs_get_node_info(sbi, nid, &ni);
if (ni.blk_addr != start_addr + off) { if (ni.blk_addr != start_addr + off) {
f2fs_put_page(node_page, 1); f2fs_put_page(node_page, 1);
continue; continue;
} }
move_node_page(node_page, gc_type); f2fs_move_node_page(node_page, gc_type);
stat_inc_node_blk_count(sbi, 1, gc_type); stat_inc_node_blk_count(sbi, 1, gc_type);
} }
if (++phase < 3) if (++phase < 3)
goto next_step; goto next_step;
if (fggc)
atomic_dec(&sbi->wb_sync_req[NODE]);
} }
/* /*
...@@ -545,7 +541,7 @@ static void gc_node_segment(struct f2fs_sb_info *sbi, ...@@ -545,7 +541,7 @@ static void gc_node_segment(struct f2fs_sb_info *sbi,
* as indirect or double indirect node blocks, are given, it must be a caller's * as indirect or double indirect node blocks, are given, it must be a caller's
* bug. * bug.
*/ */
block_t start_bidx_of_node(unsigned int node_ofs, struct inode *inode) block_t f2fs_start_bidx_of_node(unsigned int node_ofs, struct inode *inode)
{ {
unsigned int indirect_blks = 2 * NIDS_PER_BLOCK + 4; unsigned int indirect_blks = 2 * NIDS_PER_BLOCK + 4;
unsigned int bidx; unsigned int bidx;
...@@ -576,11 +572,11 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, ...@@ -576,11 +572,11 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
nid = le32_to_cpu(sum->nid); nid = le32_to_cpu(sum->nid);
ofs_in_node = le16_to_cpu(sum->ofs_in_node); ofs_in_node = le16_to_cpu(sum->ofs_in_node);
node_page = get_node_page(sbi, nid); node_page = f2fs_get_node_page(sbi, nid);
if (IS_ERR(node_page)) if (IS_ERR(node_page))
return false; return false;
get_node_info(sbi, nid, dni); f2fs_get_node_info(sbi, nid, dni);
if (sum->version != dni->version) { if (sum->version != dni->version) {
f2fs_msg(sbi->sb, KERN_WARNING, f2fs_msg(sbi->sb, KERN_WARNING,
...@@ -603,7 +599,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, ...@@ -603,7 +599,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
* This can be used to move blocks, aka LBAs, directly on disk. * This can be used to move blocks, aka LBAs, directly on disk.
*/ */
static void move_data_block(struct inode *inode, block_t bidx, static void move_data_block(struct inode *inode, block_t bidx,
unsigned int segno, int off) int gc_type, unsigned int segno, int off)
{ {
struct f2fs_io_info fio = { struct f2fs_io_info fio = {
.sbi = F2FS_I_SB(inode), .sbi = F2FS_I_SB(inode),
...@@ -614,6 +610,7 @@ static void move_data_block(struct inode *inode, block_t bidx, ...@@ -614,6 +610,7 @@ static void move_data_block(struct inode *inode, block_t bidx,
.op_flags = 0, .op_flags = 0,
.encrypted_page = NULL, .encrypted_page = NULL,
.in_list = false, .in_list = false,
.retry = false,
}; };
struct dnode_of_data dn; struct dnode_of_data dn;
struct f2fs_summary sum; struct f2fs_summary sum;
...@@ -621,6 +618,7 @@ static void move_data_block(struct inode *inode, block_t bidx, ...@@ -621,6 +618,7 @@ static void move_data_block(struct inode *inode, block_t bidx,
struct page *page; struct page *page;
block_t newaddr; block_t newaddr;
int err; int err;
bool lfs_mode = test_opt(fio.sbi, LFS);
/* do not read out */ /* do not read out */
page = f2fs_grab_cache_page(inode->i_mapping, bidx, false); page = f2fs_grab_cache_page(inode->i_mapping, bidx, false);
...@@ -630,8 +628,11 @@ static void move_data_block(struct inode *inode, block_t bidx, ...@@ -630,8 +628,11 @@ static void move_data_block(struct inode *inode, block_t bidx,
if (!check_valid_map(F2FS_I_SB(inode), segno, off)) if (!check_valid_map(F2FS_I_SB(inode), segno, off))
goto out; goto out;
if (f2fs_is_atomic_file(inode)) if (f2fs_is_atomic_file(inode)) {
F2FS_I(inode)->i_gc_failures[GC_FAILURE_ATOMIC]++;
F2FS_I_SB(inode)->skipped_atomic_files[gc_type]++;
goto out; goto out;
}
if (f2fs_is_pinned_file(inode)) { if (f2fs_is_pinned_file(inode)) {
f2fs_pin_file_control(inode, true); f2fs_pin_file_control(inode, true);
...@@ -639,7 +640,7 @@ static void move_data_block(struct inode *inode, block_t bidx, ...@@ -639,7 +640,7 @@ static void move_data_block(struct inode *inode, block_t bidx,
} }
set_new_dnode(&dn, inode, NULL, NULL, 0); set_new_dnode(&dn, inode, NULL, NULL, 0);
err = get_dnode_of_data(&dn, bidx, LOOKUP_NODE); err = f2fs_get_dnode_of_data(&dn, bidx, LOOKUP_NODE);
if (err) if (err)
goto out; goto out;
...@@ -654,14 +655,17 @@ static void move_data_block(struct inode *inode, block_t bidx, ...@@ -654,14 +655,17 @@ static void move_data_block(struct inode *inode, block_t bidx,
*/ */
f2fs_wait_on_page_writeback(page, DATA, true); f2fs_wait_on_page_writeback(page, DATA, true);
get_node_info(fio.sbi, dn.nid, &ni); f2fs_get_node_info(fio.sbi, dn.nid, &ni);
set_summary(&sum, dn.nid, dn.ofs_in_node, ni.version); set_summary(&sum, dn.nid, dn.ofs_in_node, ni.version);
/* read page */ /* read page */
fio.page = page; fio.page = page;
fio.new_blkaddr = fio.old_blkaddr = dn.data_blkaddr; fio.new_blkaddr = fio.old_blkaddr = dn.data_blkaddr;
allocate_data_block(fio.sbi, NULL, fio.old_blkaddr, &newaddr, if (lfs_mode)
down_write(&fio.sbi->io_order_lock);
f2fs_allocate_data_block(fio.sbi, NULL, fio.old_blkaddr, &newaddr,
&sum, CURSEG_COLD_DATA, NULL, false); &sum, CURSEG_COLD_DATA, NULL, false);
fio.encrypted_page = f2fs_pagecache_get_page(META_MAPPING(fio.sbi), fio.encrypted_page = f2fs_pagecache_get_page(META_MAPPING(fio.sbi),
...@@ -693,6 +697,7 @@ static void move_data_block(struct inode *inode, block_t bidx, ...@@ -693,6 +697,7 @@ static void move_data_block(struct inode *inode, block_t bidx,
dec_page_count(fio.sbi, F2FS_DIRTY_META); dec_page_count(fio.sbi, F2FS_DIRTY_META);
set_page_writeback(fio.encrypted_page); set_page_writeback(fio.encrypted_page);
ClearPageError(page);
/* allocate block address */ /* allocate block address */
f2fs_wait_on_page_writeback(dn.node_page, NODE, true); f2fs_wait_on_page_writeback(dn.node_page, NODE, true);
...@@ -700,8 +705,8 @@ static void move_data_block(struct inode *inode, block_t bidx, ...@@ -700,8 +705,8 @@ static void move_data_block(struct inode *inode, block_t bidx,
fio.op = REQ_OP_WRITE; fio.op = REQ_OP_WRITE;
fio.op_flags = REQ_SYNC; fio.op_flags = REQ_SYNC;
fio.new_blkaddr = newaddr; fio.new_blkaddr = newaddr;
err = f2fs_submit_page_write(&fio); f2fs_submit_page_write(&fio);
if (err) { if (fio.retry) {
if (PageWriteback(fio.encrypted_page)) if (PageWriteback(fio.encrypted_page))
end_page_writeback(fio.encrypted_page); end_page_writeback(fio.encrypted_page);
goto put_page_out; goto put_page_out;
...@@ -716,8 +721,10 @@ static void move_data_block(struct inode *inode, block_t bidx, ...@@ -716,8 +721,10 @@ static void move_data_block(struct inode *inode, block_t bidx,
put_page_out: put_page_out:
f2fs_put_page(fio.encrypted_page, 1); f2fs_put_page(fio.encrypted_page, 1);
recover_block: recover_block:
if (lfs_mode)
up_write(&fio.sbi->io_order_lock);
if (err) if (err)
__f2fs_replace_block(fio.sbi, &sum, newaddr, fio.old_blkaddr, f2fs_do_replace_block(fio.sbi, &sum, newaddr, fio.old_blkaddr,
true, true); true, true);
put_out: put_out:
f2fs_put_dnode(&dn); f2fs_put_dnode(&dn);
...@@ -730,15 +737,18 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type, ...@@ -730,15 +737,18 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type,
{ {
struct page *page; struct page *page;
page = get_lock_data_page(inode, bidx, true); page = f2fs_get_lock_data_page(inode, bidx, true);
if (IS_ERR(page)) if (IS_ERR(page))
return; return;
if (!check_valid_map(F2FS_I_SB(inode), segno, off)) if (!check_valid_map(F2FS_I_SB(inode), segno, off))
goto out; goto out;
if (f2fs_is_atomic_file(inode)) if (f2fs_is_atomic_file(inode)) {
F2FS_I(inode)->i_gc_failures[GC_FAILURE_ATOMIC]++;
F2FS_I_SB(inode)->skipped_atomic_files[gc_type]++;
goto out; goto out;
}
if (f2fs_is_pinned_file(inode)) { if (f2fs_is_pinned_file(inode)) {
if (gc_type == FG_GC) if (gc_type == FG_GC)
f2fs_pin_file_control(inode, true); f2fs_pin_file_control(inode, true);
...@@ -772,15 +782,20 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type, ...@@ -772,15 +782,20 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type,
f2fs_wait_on_page_writeback(page, DATA, true); f2fs_wait_on_page_writeback(page, DATA, true);
if (clear_page_dirty_for_io(page)) { if (clear_page_dirty_for_io(page)) {
inode_dec_dirty_pages(inode); inode_dec_dirty_pages(inode);
remove_dirty_inode(inode); f2fs_remove_dirty_inode(inode);
} }
set_cold_data(page); set_cold_data(page);
err = do_write_data_page(&fio); err = f2fs_do_write_data_page(&fio);
if (err == -ENOMEM && is_dirty) { if (err) {
congestion_wait(BLK_RW_ASYNC, HZ/50); clear_cold_data(page);
goto retry; if (err == -ENOMEM) {
congestion_wait(BLK_RW_ASYNC, HZ/50);
goto retry;
}
if (is_dirty)
set_page_dirty(page);
} }
} }
out: out:
...@@ -824,13 +839,13 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, ...@@ -824,13 +839,13 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
continue; continue;
if (phase == 0) { if (phase == 0) {
ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), 1, f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), 1,
META_NAT, true); META_NAT, true);
continue; continue;
} }
if (phase == 1) { if (phase == 1) {
ra_node_page(sbi, nid); f2fs_ra_node_page(sbi, nid);
continue; continue;
} }
...@@ -839,7 +854,7 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, ...@@ -839,7 +854,7 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
continue; continue;
if (phase == 2) { if (phase == 2) {
ra_node_page(sbi, dni.ino); f2fs_ra_node_page(sbi, dni.ino);
continue; continue;
} }
...@@ -850,23 +865,23 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, ...@@ -850,23 +865,23 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
if (IS_ERR(inode) || is_bad_inode(inode)) if (IS_ERR(inode) || is_bad_inode(inode))
continue; continue;
/* if encrypted inode, let's go phase 3 */ /* if inode uses special I/O path, let's go phase 3 */
if (f2fs_encrypted_file(inode)) { if (f2fs_post_read_required(inode)) {
add_gc_inode(gc_list, inode); add_gc_inode(gc_list, inode);
continue; continue;
} }
if (!down_write_trylock( if (!down_write_trylock(
&F2FS_I(inode)->dio_rwsem[WRITE])) { &F2FS_I(inode)->i_gc_rwsem[WRITE])) {
iput(inode); iput(inode);
continue; continue;
} }
start_bidx = start_bidx_of_node(nofs, inode); start_bidx = f2fs_start_bidx_of_node(nofs, inode);
data_page = get_read_data_page(inode, data_page = f2fs_get_read_data_page(inode,
start_bidx + ofs_in_node, REQ_RAHEAD, start_bidx + ofs_in_node, REQ_RAHEAD,
true); true);
up_write(&F2FS_I(inode)->dio_rwsem[WRITE]); up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
if (IS_ERR(data_page)) { if (IS_ERR(data_page)) {
iput(inode); iput(inode);
continue; continue;
...@@ -884,11 +899,11 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, ...@@ -884,11 +899,11 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
bool locked = false; bool locked = false;
if (S_ISREG(inode->i_mode)) { if (S_ISREG(inode->i_mode)) {
if (!down_write_trylock(&fi->dio_rwsem[READ])) if (!down_write_trylock(&fi->i_gc_rwsem[READ]))
continue; continue;
if (!down_write_trylock( if (!down_write_trylock(
&fi->dio_rwsem[WRITE])) { &fi->i_gc_rwsem[WRITE])) {
up_write(&fi->dio_rwsem[READ]); up_write(&fi->i_gc_rwsem[READ]);
continue; continue;
} }
locked = true; locked = true;
...@@ -897,17 +912,18 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, ...@@ -897,17 +912,18 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
inode_dio_wait(inode); inode_dio_wait(inode);
} }
start_bidx = start_bidx_of_node(nofs, inode) start_bidx = f2fs_start_bidx_of_node(nofs, inode)
+ ofs_in_node; + ofs_in_node;
if (f2fs_encrypted_file(inode)) if (f2fs_post_read_required(inode))
move_data_block(inode, start_bidx, segno, off); move_data_block(inode, start_bidx, gc_type,
segno, off);
else else
move_data_page(inode, start_bidx, gc_type, move_data_page(inode, start_bidx, gc_type,
segno, off); segno, off);
if (locked) { if (locked) {
up_write(&fi->dio_rwsem[WRITE]); up_write(&fi->i_gc_rwsem[WRITE]);
up_write(&fi->dio_rwsem[READ]); up_write(&fi->i_gc_rwsem[READ]);
} }
stat_inc_data_blk_count(sbi, 1, gc_type); stat_inc_data_blk_count(sbi, 1, gc_type);
...@@ -946,12 +962,12 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, ...@@ -946,12 +962,12 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
/* readahead multi ssa blocks those have contiguous address */ /* readahead multi ssa blocks those have contiguous address */
if (sbi->segs_per_sec > 1) if (sbi->segs_per_sec > 1)
ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno), f2fs_ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno),
sbi->segs_per_sec, META_SSA, true); sbi->segs_per_sec, META_SSA, true);
/* reference all summary page */ /* reference all summary page */
while (segno < end_segno) { while (segno < end_segno) {
sum_page = get_sum_page(sbi, segno++); sum_page = f2fs_get_sum_page(sbi, segno++);
unlock_page(sum_page); unlock_page(sum_page);
} }
...@@ -1017,6 +1033,8 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, ...@@ -1017,6 +1033,8 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync,
.ilist = LIST_HEAD_INIT(gc_list.ilist), .ilist = LIST_HEAD_INIT(gc_list.ilist),
.iroot = RADIX_TREE_INIT(gc_list.iroot, GFP_NOFS), .iroot = RADIX_TREE_INIT(gc_list.iroot, GFP_NOFS),
}; };
unsigned long long last_skipped = sbi->skipped_atomic_files[FG_GC];
unsigned int skipped_round = 0, round = 0;
trace_f2fs_gc_begin(sbi->sb, sync, background, trace_f2fs_gc_begin(sbi->sb, sync, background,
get_pages(sbi, F2FS_DIRTY_NODES), get_pages(sbi, F2FS_DIRTY_NODES),
...@@ -1045,7 +1063,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, ...@@ -1045,7 +1063,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync,
* secure free segments which doesn't need fggc any more. * secure free segments which doesn't need fggc any more.
*/ */
if (prefree_segments(sbi)) { if (prefree_segments(sbi)) {
ret = write_checkpoint(sbi, &cpc); ret = f2fs_write_checkpoint(sbi, &cpc);
if (ret) if (ret)
goto stop; goto stop;
} }
...@@ -1068,17 +1086,27 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, ...@@ -1068,17 +1086,27 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync,
sec_freed++; sec_freed++;
total_freed += seg_freed; total_freed += seg_freed;
if (gc_type == FG_GC) {
if (sbi->skipped_atomic_files[FG_GC] > last_skipped)
skipped_round++;
last_skipped = sbi->skipped_atomic_files[FG_GC];
round++;
}
if (gc_type == FG_GC) if (gc_type == FG_GC)
sbi->cur_victim_sec = NULL_SEGNO; sbi->cur_victim_sec = NULL_SEGNO;
if (!sync) { if (!sync) {
if (has_not_enough_free_secs(sbi, sec_freed, 0)) { if (has_not_enough_free_secs(sbi, sec_freed, 0)) {
if (skipped_round > MAX_SKIP_ATOMIC_COUNT &&
skipped_round * 2 >= round)
f2fs_drop_inmem_pages_all(sbi, true);
segno = NULL_SEGNO; segno = NULL_SEGNO;
goto gc_more; goto gc_more;
} }
if (gc_type == FG_GC) if (gc_type == FG_GC)
ret = write_checkpoint(sbi, &cpc); ret = f2fs_write_checkpoint(sbi, &cpc);
} }
stop: stop:
SIT_I(sbi)->last_victim[ALLOC_NEXT] = 0; SIT_I(sbi)->last_victim[ALLOC_NEXT] = 0;
...@@ -1102,19 +1130,10 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, ...@@ -1102,19 +1130,10 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync,
return ret; return ret;
} }
void build_gc_manager(struct f2fs_sb_info *sbi) void f2fs_build_gc_manager(struct f2fs_sb_info *sbi)
{ {
u64 main_count, resv_count, ovp_count;
DIRTY_I(sbi)->v_ops = &default_v_ops; DIRTY_I(sbi)->v_ops = &default_v_ops;
/* threshold of # of valid blocks in a section for victims of FG_GC */
main_count = SM_I(sbi)->main_segments << sbi->log_blocks_per_seg;
resv_count = SM_I(sbi)->reserved_segments << sbi->log_blocks_per_seg;
ovp_count = SM_I(sbi)->ovp_segments << sbi->log_blocks_per_seg;
sbi->fggc_threshold = div64_u64((main_count - ovp_count) *
BLKS_PER_SEC(sbi), (main_count - resv_count));
sbi->gc_pin_file_threshold = DEF_GC_FAILED_PINNED_FILES; sbi->gc_pin_file_threshold = DEF_GC_FAILED_PINNED_FILES;
/* give warm/cold data area from slower device */ /* give warm/cold data area from slower device */
......
...@@ -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;
}; };
......
...@@ -25,7 +25,7 @@ bool f2fs_may_inline_data(struct inode *inode) ...@@ -25,7 +25,7 @@ bool f2fs_may_inline_data(struct inode *inode)
if (i_size_read(inode) > MAX_INLINE_DATA(inode)) if (i_size_read(inode) > MAX_INLINE_DATA(inode))
return false; return false;
if (f2fs_encrypted_file(inode)) if (f2fs_post_read_required(inode))
return false; return false;
return true; return true;
...@@ -42,7 +42,7 @@ bool f2fs_may_inline_dentry(struct inode *inode) ...@@ -42,7 +42,7 @@ bool f2fs_may_inline_dentry(struct inode *inode)
return true; return true;
} }
void read_inline_data(struct page *page, struct page *ipage) void f2fs_do_read_inline_data(struct page *page, struct page *ipage)
{ {
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
void *src_addr, *dst_addr; void *src_addr, *dst_addr;
...@@ -64,7 +64,8 @@ void read_inline_data(struct page *page, struct page *ipage) ...@@ -64,7 +64,8 @@ void read_inline_data(struct page *page, struct page *ipage)
SetPageUptodate(page); SetPageUptodate(page);
} }
void truncate_inline_inode(struct inode *inode, struct page *ipage, u64 from) void f2fs_truncate_inline_inode(struct inode *inode,
struct page *ipage, u64 from)
{ {
void *addr; void *addr;
...@@ -85,7 +86,7 @@ int f2fs_read_inline_data(struct inode *inode, struct page *page) ...@@ -85,7 +86,7 @@ int f2fs_read_inline_data(struct inode *inode, struct page *page)
{ {
struct page *ipage; struct page *ipage;
ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino); ipage = f2fs_get_node_page(F2FS_I_SB(inode), inode->i_ino);
if (IS_ERR(ipage)) { if (IS_ERR(ipage)) {
unlock_page(page); unlock_page(page);
return PTR_ERR(ipage); return PTR_ERR(ipage);
...@@ -99,7 +100,7 @@ int f2fs_read_inline_data(struct inode *inode, struct page *page) ...@@ -99,7 +100,7 @@ int f2fs_read_inline_data(struct inode *inode, struct page *page)
if (page->index) if (page->index)
zero_user_segment(page, 0, PAGE_SIZE); zero_user_segment(page, 0, PAGE_SIZE);
else else
read_inline_data(page, ipage); f2fs_do_read_inline_data(page, ipage);
if (!PageUptodate(page)) if (!PageUptodate(page))
SetPageUptodate(page); SetPageUptodate(page);
...@@ -131,7 +132,7 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page) ...@@ -131,7 +132,7 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
f2fs_bug_on(F2FS_P_SB(page), PageWriteback(page)); f2fs_bug_on(F2FS_P_SB(page), PageWriteback(page));
read_inline_data(page, dn->inode_page); f2fs_do_read_inline_data(page, dn->inode_page);
set_page_dirty(page); set_page_dirty(page);
/* clear dirty state */ /* clear dirty state */
...@@ -139,20 +140,21 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page) ...@@ -139,20 +140,21 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
/* write data page to try to make data consistent */ /* write data page to try to make data consistent */
set_page_writeback(page); set_page_writeback(page);
ClearPageError(page);
fio.old_blkaddr = dn->data_blkaddr; fio.old_blkaddr = dn->data_blkaddr;
set_inode_flag(dn->inode, FI_HOT_DATA); set_inode_flag(dn->inode, FI_HOT_DATA);
write_data_page(dn, &fio); f2fs_outplace_write_data(dn, &fio);
f2fs_wait_on_page_writeback(page, DATA, true); f2fs_wait_on_page_writeback(page, DATA, true);
if (dirty) { if (dirty) {
inode_dec_dirty_pages(dn->inode); inode_dec_dirty_pages(dn->inode);
remove_dirty_inode(dn->inode); f2fs_remove_dirty_inode(dn->inode);
} }
/* this converted inline_data should be recovered. */ /* this converted inline_data should be recovered. */
set_inode_flag(dn->inode, FI_APPEND_WRITE); set_inode_flag(dn->inode, FI_APPEND_WRITE);
/* clear inline data and flag after data writeback */ /* clear inline data and flag after data writeback */
truncate_inline_inode(dn->inode, dn->inode_page, 0); f2fs_truncate_inline_inode(dn->inode, dn->inode_page, 0);
clear_inline_node(dn->inode_page); clear_inline_node(dn->inode_page);
clear_out: clear_out:
stat_dec_inline_inode(dn->inode); stat_dec_inline_inode(dn->inode);
...@@ -177,7 +179,7 @@ int f2fs_convert_inline_inode(struct inode *inode) ...@@ -177,7 +179,7 @@ int f2fs_convert_inline_inode(struct inode *inode)
f2fs_lock_op(sbi); f2fs_lock_op(sbi);
ipage = get_node_page(sbi, inode->i_ino); ipage = f2fs_get_node_page(sbi, inode->i_ino);
if (IS_ERR(ipage)) { if (IS_ERR(ipage)) {
err = PTR_ERR(ipage); err = PTR_ERR(ipage);
goto out; goto out;
...@@ -203,12 +205,10 @@ int f2fs_write_inline_data(struct inode *inode, struct page *page) ...@@ -203,12 +205,10 @@ int f2fs_write_inline_data(struct inode *inode, struct page *page)
{ {
void *src_addr, *dst_addr; void *src_addr, *dst_addr;
struct dnode_of_data dn; struct dnode_of_data dn;
struct address_space *mapping = page_mapping(page);
unsigned long flags;
int err; int err;
set_new_dnode(&dn, inode, NULL, NULL, 0); set_new_dnode(&dn, inode, NULL, NULL, 0);
err = get_dnode_of_data(&dn, 0, LOOKUP_NODE); err = f2fs_get_dnode_of_data(&dn, 0, LOOKUP_NODE);
if (err) if (err)
return err; return err;
...@@ -226,10 +226,7 @@ int f2fs_write_inline_data(struct inode *inode, struct page *page) ...@@ -226,10 +226,7 @@ int f2fs_write_inline_data(struct inode *inode, struct page *page)
kunmap_atomic(src_addr); kunmap_atomic(src_addr);
set_page_dirty(dn.inode_page); set_page_dirty(dn.inode_page);
xa_lock_irqsave(&mapping->i_pages, flags); f2fs_clear_radix_tree_dirty_tag(page);
radix_tree_tag_clear(&mapping->i_pages, page_index(page),
PAGECACHE_TAG_DIRTY);
xa_unlock_irqrestore(&mapping->i_pages, flags);
set_inode_flag(inode, FI_APPEND_WRITE); set_inode_flag(inode, FI_APPEND_WRITE);
set_inode_flag(inode, FI_DATA_EXIST); set_inode_flag(inode, FI_DATA_EXIST);
...@@ -239,7 +236,7 @@ int f2fs_write_inline_data(struct inode *inode, struct page *page) ...@@ -239,7 +236,7 @@ int f2fs_write_inline_data(struct inode *inode, struct page *page)
return 0; return 0;
} }
bool recover_inline_data(struct inode *inode, struct page *npage) bool f2fs_recover_inline_data(struct inode *inode, struct page *npage)
{ {
struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct f2fs_inode *ri = NULL; struct f2fs_inode *ri = NULL;
...@@ -260,7 +257,7 @@ bool recover_inline_data(struct inode *inode, struct page *npage) ...@@ -260,7 +257,7 @@ bool recover_inline_data(struct inode *inode, struct page *npage)
if (f2fs_has_inline_data(inode) && if (f2fs_has_inline_data(inode) &&
ri && (ri->i_inline & F2FS_INLINE_DATA)) { ri && (ri->i_inline & F2FS_INLINE_DATA)) {
process_inline: process_inline:
ipage = get_node_page(sbi, inode->i_ino); ipage = f2fs_get_node_page(sbi, inode->i_ino);
f2fs_bug_on(sbi, IS_ERR(ipage)); f2fs_bug_on(sbi, IS_ERR(ipage));
f2fs_wait_on_page_writeback(ipage, NODE, true); f2fs_wait_on_page_writeback(ipage, NODE, true);
...@@ -278,20 +275,20 @@ bool recover_inline_data(struct inode *inode, struct page *npage) ...@@ -278,20 +275,20 @@ bool recover_inline_data(struct inode *inode, struct page *npage)
} }
if (f2fs_has_inline_data(inode)) { if (f2fs_has_inline_data(inode)) {
ipage = get_node_page(sbi, inode->i_ino); ipage = f2fs_get_node_page(sbi, inode->i_ino);
f2fs_bug_on(sbi, IS_ERR(ipage)); f2fs_bug_on(sbi, IS_ERR(ipage));
truncate_inline_inode(inode, ipage, 0); f2fs_truncate_inline_inode(inode, ipage, 0);
clear_inode_flag(inode, FI_INLINE_DATA); clear_inode_flag(inode, FI_INLINE_DATA);
f2fs_put_page(ipage, 1); f2fs_put_page(ipage, 1);
} else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) { } else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) {
if (truncate_blocks(inode, 0, false)) if (f2fs_truncate_blocks(inode, 0, false))
return false; return false;
goto process_inline; goto process_inline;
} }
return false; return false;
} }
struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir, struct f2fs_dir_entry *f2fs_find_in_inline_dir(struct inode *dir,
struct fscrypt_name *fname, struct page **res_page) struct fscrypt_name *fname, struct page **res_page)
{ {
struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb);
...@@ -302,7 +299,7 @@ struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir, ...@@ -302,7 +299,7 @@ struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir,
void *inline_dentry; void *inline_dentry;
f2fs_hash_t namehash; f2fs_hash_t namehash;
ipage = get_node_page(sbi, dir->i_ino); ipage = f2fs_get_node_page(sbi, dir->i_ino);
if (IS_ERR(ipage)) { if (IS_ERR(ipage)) {
*res_page = ipage; *res_page = ipage;
return NULL; return NULL;
...@@ -313,7 +310,7 @@ struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir, ...@@ -313,7 +310,7 @@ struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir,
inline_dentry = inline_data_addr(dir, ipage); inline_dentry = inline_data_addr(dir, ipage);
make_dentry_ptr_inline(dir, &d, inline_dentry); make_dentry_ptr_inline(dir, &d, inline_dentry);
de = find_target_dentry(fname, namehash, NULL, &d); de = f2fs_find_target_dentry(fname, namehash, NULL, &d);
unlock_page(ipage); unlock_page(ipage);
if (de) if (de)
*res_page = ipage; *res_page = ipage;
...@@ -323,7 +320,7 @@ struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir, ...@@ -323,7 +320,7 @@ struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir,
return de; return de;
} }
int make_empty_inline_dir(struct inode *inode, struct inode *parent, int f2fs_make_empty_inline_dir(struct inode *inode, struct inode *parent,
struct page *ipage) struct page *ipage)
{ {
struct f2fs_dentry_ptr d; struct f2fs_dentry_ptr d;
...@@ -332,7 +329,7 @@ int make_empty_inline_dir(struct inode *inode, struct inode *parent, ...@@ -332,7 +329,7 @@ int make_empty_inline_dir(struct inode *inode, struct inode *parent,
inline_dentry = inline_data_addr(inode, ipage); inline_dentry = inline_data_addr(inode, ipage);
make_dentry_ptr_inline(inode, &d, inline_dentry); make_dentry_ptr_inline(inode, &d, inline_dentry);
do_make_empty_dir(inode, parent, &d); f2fs_do_make_empty_dir(inode, parent, &d);
set_page_dirty(ipage); set_page_dirty(ipage);
...@@ -367,7 +364,6 @@ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage, ...@@ -367,7 +364,6 @@ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage,
goto out; goto out;
f2fs_wait_on_page_writeback(page, DATA, true); f2fs_wait_on_page_writeback(page, DATA, true);
zero_user_segment(page, MAX_INLINE_DATA(dir), PAGE_SIZE);
dentry_blk = page_address(page); dentry_blk = page_address(page);
...@@ -391,7 +387,7 @@ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage, ...@@ -391,7 +387,7 @@ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage,
set_page_dirty(page); set_page_dirty(page);
/* clear inline dir and flag after data writeback */ /* clear inline dir and flag after data writeback */
truncate_inline_inode(dir, ipage, 0); f2fs_truncate_inline_inode(dir, ipage, 0);
stat_dec_inline_dir(dir); stat_dec_inline_dir(dir);
clear_inode_flag(dir, FI_INLINE_DENTRY); clear_inode_flag(dir, FI_INLINE_DENTRY);
...@@ -434,7 +430,7 @@ static int f2fs_add_inline_entries(struct inode *dir, void *inline_dentry) ...@@ -434,7 +430,7 @@ static int f2fs_add_inline_entries(struct inode *dir, void *inline_dentry)
new_name.len = le16_to_cpu(de->name_len); new_name.len = le16_to_cpu(de->name_len);
ino = le32_to_cpu(de->ino); ino = le32_to_cpu(de->ino);
fake_mode = get_de_type(de) << S_SHIFT; fake_mode = f2fs_get_de_type(de) << S_SHIFT;
err = f2fs_add_regular_entry(dir, &new_name, NULL, NULL, err = f2fs_add_regular_entry(dir, &new_name, NULL, NULL,
ino, fake_mode); ino, fake_mode);
...@@ -446,8 +442,8 @@ static int f2fs_add_inline_entries(struct inode *dir, void *inline_dentry) ...@@ -446,8 +442,8 @@ static int f2fs_add_inline_entries(struct inode *dir, void *inline_dentry)
return 0; return 0;
punch_dentry_pages: punch_dentry_pages:
truncate_inode_pages(&dir->i_data, 0); truncate_inode_pages(&dir->i_data, 0);
truncate_blocks(dir, 0, false); f2fs_truncate_blocks(dir, 0, false);
remove_dirty_inode(dir); f2fs_remove_dirty_inode(dir);
return err; return err;
} }
...@@ -465,7 +461,7 @@ static int f2fs_move_rehashed_dirents(struct inode *dir, struct page *ipage, ...@@ -465,7 +461,7 @@ static int f2fs_move_rehashed_dirents(struct inode *dir, struct page *ipage,
} }
memcpy(backup_dentry, inline_dentry, MAX_INLINE_DATA(dir)); memcpy(backup_dentry, inline_dentry, MAX_INLINE_DATA(dir));
truncate_inline_inode(dir, ipage, 0); f2fs_truncate_inline_inode(dir, ipage, 0);
unlock_page(ipage); unlock_page(ipage);
...@@ -514,14 +510,14 @@ int f2fs_add_inline_entry(struct inode *dir, const struct qstr *new_name, ...@@ -514,14 +510,14 @@ int f2fs_add_inline_entry(struct inode *dir, const struct qstr *new_name,
struct page *page = NULL; struct page *page = NULL;
int err = 0; int err = 0;
ipage = get_node_page(sbi, dir->i_ino); ipage = f2fs_get_node_page(sbi, dir->i_ino);
if (IS_ERR(ipage)) if (IS_ERR(ipage))
return PTR_ERR(ipage); return PTR_ERR(ipage);
inline_dentry = inline_data_addr(dir, ipage); inline_dentry = inline_data_addr(dir, ipage);
make_dentry_ptr_inline(dir, &d, inline_dentry); make_dentry_ptr_inline(dir, &d, inline_dentry);
bit_pos = room_for_filename(d.bitmap, slots, d.max); bit_pos = f2fs_room_for_filename(d.bitmap, slots, d.max);
if (bit_pos >= d.max) { if (bit_pos >= d.max) {
err = f2fs_convert_inline_dir(dir, ipage, inline_dentry); err = f2fs_convert_inline_dir(dir, ipage, inline_dentry);
if (err) if (err)
...@@ -532,7 +528,7 @@ int f2fs_add_inline_entry(struct inode *dir, const struct qstr *new_name, ...@@ -532,7 +528,7 @@ int f2fs_add_inline_entry(struct inode *dir, const struct qstr *new_name,
if (inode) { if (inode) {
down_write(&F2FS_I(inode)->i_sem); down_write(&F2FS_I(inode)->i_sem);
page = init_inode_metadata(inode, dir, new_name, page = f2fs_init_inode_metadata(inode, dir, new_name,
orig_name, ipage); orig_name, ipage);
if (IS_ERR(page)) { if (IS_ERR(page)) {
err = PTR_ERR(page); err = PTR_ERR(page);
...@@ -553,7 +549,7 @@ int f2fs_add_inline_entry(struct inode *dir, const struct qstr *new_name, ...@@ -553,7 +549,7 @@ int f2fs_add_inline_entry(struct inode *dir, const struct qstr *new_name,
f2fs_put_page(page, 1); f2fs_put_page(page, 1);
} }
update_parent_metadata(dir, inode, 0); f2fs_update_parent_metadata(dir, inode, 0);
fail: fail:
if (inode) if (inode)
up_write(&F2FS_I(inode)->i_sem); up_write(&F2FS_I(inode)->i_sem);
...@@ -599,7 +595,7 @@ bool f2fs_empty_inline_dir(struct inode *dir) ...@@ -599,7 +595,7 @@ bool f2fs_empty_inline_dir(struct inode *dir)
void *inline_dentry; void *inline_dentry;
struct f2fs_dentry_ptr d; struct f2fs_dentry_ptr d;
ipage = get_node_page(sbi, dir->i_ino); ipage = f2fs_get_node_page(sbi, dir->i_ino);
if (IS_ERR(ipage)) if (IS_ERR(ipage))
return false; return false;
...@@ -630,7 +626,7 @@ int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx, ...@@ -630,7 +626,7 @@ int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx,
if (ctx->pos == d.max) if (ctx->pos == d.max)
return 0; return 0;
ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino); ipage = f2fs_get_node_page(F2FS_I_SB(inode), inode->i_ino);
if (IS_ERR(ipage)) if (IS_ERR(ipage))
return PTR_ERR(ipage); return PTR_ERR(ipage);
...@@ -656,7 +652,7 @@ int f2fs_inline_data_fiemap(struct inode *inode, ...@@ -656,7 +652,7 @@ int f2fs_inline_data_fiemap(struct inode *inode,
struct page *ipage; struct page *ipage;
int err = 0; int err = 0;
ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino); ipage = f2fs_get_node_page(F2FS_I_SB(inode), inode->i_ino);
if (IS_ERR(ipage)) if (IS_ERR(ipage))
return PTR_ERR(ipage); return PTR_ERR(ipage);
...@@ -672,7 +668,7 @@ int f2fs_inline_data_fiemap(struct inode *inode, ...@@ -672,7 +668,7 @@ int f2fs_inline_data_fiemap(struct inode *inode,
ilen = start + len; ilen = start + len;
ilen -= start; ilen -= start;
get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni); f2fs_get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni);
byteaddr = (__u64)ni.blk_addr << inode->i_sb->s_blocksize_bits; byteaddr = (__u64)ni.blk_addr << inode->i_sb->s_blocksize_bits;
byteaddr += (char *)inline_data_addr(inode, ipage) - byteaddr += (char *)inline_data_addr(inode, ipage) -
(char *)F2FS_INODE(ipage); (char *)F2FS_INODE(ipage);
......
...@@ -36,15 +36,15 @@ void f2fs_set_inode_flags(struct inode *inode) ...@@ -36,15 +36,15 @@ void f2fs_set_inode_flags(struct inode *inode)
unsigned int flags = F2FS_I(inode)->i_flags; unsigned int flags = F2FS_I(inode)->i_flags;
unsigned int new_fl = 0; unsigned int new_fl = 0;
if (flags & FS_SYNC_FL) if (flags & F2FS_SYNC_FL)
new_fl |= S_SYNC; new_fl |= S_SYNC;
if (flags & FS_APPEND_FL) if (flags & F2FS_APPEND_FL)
new_fl |= S_APPEND; new_fl |= S_APPEND;
if (flags & FS_IMMUTABLE_FL) if (flags & F2FS_IMMUTABLE_FL)
new_fl |= S_IMMUTABLE; new_fl |= S_IMMUTABLE;
if (flags & FS_NOATIME_FL) if (flags & F2FS_NOATIME_FL)
new_fl |= S_NOATIME; new_fl |= S_NOATIME;
if (flags & FS_DIRSYNC_FL) if (flags & F2FS_DIRSYNC_FL)
new_fl |= S_DIRSYNC; new_fl |= S_DIRSYNC;
if (f2fs_encrypted_inode(inode)) if (f2fs_encrypted_inode(inode))
new_fl |= S_ENCRYPTED; new_fl |= S_ENCRYPTED;
...@@ -72,7 +72,7 @@ static bool __written_first_block(struct f2fs_inode *ri) ...@@ -72,7 +72,7 @@ static bool __written_first_block(struct f2fs_inode *ri)
{ {
block_t addr = le32_to_cpu(ri->i_addr[offset_in_addr(ri)]); block_t addr = le32_to_cpu(ri->i_addr[offset_in_addr(ri)]);
if (addr != NEW_ADDR && addr != NULL_ADDR) if (is_valid_blkaddr(addr))
return true; return true;
return false; return false;
} }
...@@ -117,7 +117,6 @@ static void __recover_inline_status(struct inode *inode, struct page *ipage) ...@@ -117,7 +117,6 @@ static void __recover_inline_status(struct inode *inode, struct page *ipage)
static bool f2fs_enable_inode_chksum(struct f2fs_sb_info *sbi, struct page *page) static bool f2fs_enable_inode_chksum(struct f2fs_sb_info *sbi, struct page *page)
{ {
struct f2fs_inode *ri = &F2FS_NODE(page)->i; struct f2fs_inode *ri = &F2FS_NODE(page)->i;
int extra_isize = le32_to_cpu(ri->i_extra_isize);
if (!f2fs_sb_has_inode_chksum(sbi->sb)) if (!f2fs_sb_has_inode_chksum(sbi->sb))
return false; return false;
...@@ -125,7 +124,8 @@ static bool f2fs_enable_inode_chksum(struct f2fs_sb_info *sbi, struct page *page ...@@ -125,7 +124,8 @@ static bool f2fs_enable_inode_chksum(struct f2fs_sb_info *sbi, struct page *page
if (!RAW_IS_INODE(F2FS_NODE(page)) || !(ri->i_inline & F2FS_EXTRA_ATTR)) if (!RAW_IS_INODE(F2FS_NODE(page)) || !(ri->i_inline & F2FS_EXTRA_ATTR))
return false; return false;
if (!F2FS_FITS_IN_INODE(ri, extra_isize, i_inode_checksum)) if (!F2FS_FITS_IN_INODE(ri, le16_to_cpu(ri->i_extra_isize),
i_inode_checksum))
return false; return false;
return true; return true;
...@@ -185,6 +185,21 @@ void f2fs_inode_chksum_set(struct f2fs_sb_info *sbi, struct page *page) ...@@ -185,6 +185,21 @@ void f2fs_inode_chksum_set(struct f2fs_sb_info *sbi, struct page *page)
ri->i_inode_checksum = cpu_to_le32(f2fs_inode_chksum(sbi, page)); ri->i_inode_checksum = cpu_to_le32(f2fs_inode_chksum(sbi, page));
} }
static bool sanity_check_inode(struct inode *inode)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
if (f2fs_sb_has_flexible_inline_xattr(sbi->sb)
&& !f2fs_has_extra_attr(inode)) {
set_sbi_flag(sbi, SBI_NEED_FSCK);
f2fs_msg(sbi->sb, KERN_WARNING,
"%s: corrupted inode ino=%lx, run fsck to fix.",
__func__, inode->i_ino);
return false;
}
return true;
}
static int do_read_inode(struct inode *inode) static int do_read_inode(struct inode *inode)
{ {
struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
...@@ -194,14 +209,10 @@ static int do_read_inode(struct inode *inode) ...@@ -194,14 +209,10 @@ static int do_read_inode(struct inode *inode)
projid_t i_projid; projid_t i_projid;
/* Check if ino is within scope */ /* Check if ino is within scope */
if (check_nid_range(sbi, inode->i_ino)) { if (f2fs_check_nid_range(sbi, inode->i_ino))
f2fs_msg(inode->i_sb, KERN_ERR, "bad inode number: %lu",
(unsigned long) inode->i_ino);
WARN_ON(1);
return -EINVAL; return -EINVAL;
}
node_page = get_node_page(sbi, inode->i_ino); node_page = f2fs_get_node_page(sbi, inode->i_ino);
if (IS_ERR(node_page)) if (IS_ERR(node_page))
return PTR_ERR(node_page); return PTR_ERR(node_page);
...@@ -221,8 +232,11 @@ static int do_read_inode(struct inode *inode) ...@@ -221,8 +232,11 @@ static int do_read_inode(struct inode *inode)
inode->i_ctime.tv_nsec = le32_to_cpu(ri->i_ctime_nsec); inode->i_ctime.tv_nsec = le32_to_cpu(ri->i_ctime_nsec);
inode->i_mtime.tv_nsec = le32_to_cpu(ri->i_mtime_nsec); inode->i_mtime.tv_nsec = le32_to_cpu(ri->i_mtime_nsec);
inode->i_generation = le32_to_cpu(ri->i_generation); inode->i_generation = le32_to_cpu(ri->i_generation);
if (S_ISDIR(inode->i_mode))
fi->i_current_depth = le32_to_cpu(ri->i_current_depth); fi->i_current_depth = le32_to_cpu(ri->i_current_depth);
else if (S_ISREG(inode->i_mode))
fi->i_gc_failures[GC_FAILURE_PIN] =
le16_to_cpu(ri->i_gc_failures);
fi->i_xattr_nid = le32_to_cpu(ri->i_xattr_nid); fi->i_xattr_nid = le32_to_cpu(ri->i_xattr_nid);
fi->i_flags = le32_to_cpu(ri->i_flags); fi->i_flags = le32_to_cpu(ri->i_flags);
fi->flags = 0; fi->flags = 0;
...@@ -239,7 +253,6 @@ static int do_read_inode(struct inode *inode) ...@@ -239,7 +253,6 @@ static int do_read_inode(struct inode *inode)
le16_to_cpu(ri->i_extra_isize) : 0; le16_to_cpu(ri->i_extra_isize) : 0;
if (f2fs_sb_has_flexible_inline_xattr(sbi->sb)) { if (f2fs_sb_has_flexible_inline_xattr(sbi->sb)) {
f2fs_bug_on(sbi, !f2fs_has_extra_attr(inode));
fi->i_inline_xattr_size = le16_to_cpu(ri->i_inline_xattr_size); fi->i_inline_xattr_size = le16_to_cpu(ri->i_inline_xattr_size);
} else if (f2fs_has_inline_xattr(inode) || } else if (f2fs_has_inline_xattr(inode) ||
f2fs_has_inline_dentry(inode)) { f2fs_has_inline_dentry(inode)) {
...@@ -265,10 +278,10 @@ static int do_read_inode(struct inode *inode) ...@@ -265,10 +278,10 @@ static int do_read_inode(struct inode *inode)
if (__written_first_block(ri)) if (__written_first_block(ri))
set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN); set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN);
if (!need_inode_block_update(sbi, inode->i_ino)) if (!f2fs_need_inode_block_update(sbi, inode->i_ino))
fi->last_disk_size = inode->i_size; fi->last_disk_size = inode->i_size;
if (fi->i_flags & FS_PROJINHERIT_FL) if (fi->i_flags & F2FS_PROJINHERIT_FL)
set_inode_flag(inode, FI_PROJ_INHERIT); set_inode_flag(inode, FI_PROJ_INHERIT);
if (f2fs_has_extra_attr(inode) && f2fs_sb_has_project_quota(sbi->sb) && if (f2fs_has_extra_attr(inode) && f2fs_sb_has_project_quota(sbi->sb) &&
...@@ -317,13 +330,17 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) ...@@ -317,13 +330,17 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino)
ret = do_read_inode(inode); ret = do_read_inode(inode);
if (ret) if (ret)
goto bad_inode; goto bad_inode;
if (!sanity_check_inode(inode)) {
ret = -EINVAL;
goto bad_inode;
}
make_now: make_now:
if (ino == F2FS_NODE_INO(sbi)) { if (ino == F2FS_NODE_INO(sbi)) {
inode->i_mapping->a_ops = &f2fs_node_aops; inode->i_mapping->a_ops = &f2fs_node_aops;
mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO); mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
} else if (ino == F2FS_META_INO(sbi)) { } else if (ino == F2FS_META_INO(sbi)) {
inode->i_mapping->a_ops = &f2fs_meta_aops; inode->i_mapping->a_ops = &f2fs_meta_aops;
mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO); mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
} else if (S_ISREG(inode->i_mode)) { } else if (S_ISREG(inode->i_mode)) {
inode->i_op = &f2fs_file_inode_operations; inode->i_op = &f2fs_file_inode_operations;
inode->i_fop = &f2fs_file_operations; inode->i_fop = &f2fs_file_operations;
...@@ -373,7 +390,7 @@ struct inode *f2fs_iget_retry(struct super_block *sb, unsigned long ino) ...@@ -373,7 +390,7 @@ struct inode *f2fs_iget_retry(struct super_block *sb, unsigned long ino)
return inode; return inode;
} }
void update_inode(struct inode *inode, struct page *node_page) void f2fs_update_inode(struct inode *inode, struct page *node_page)
{ {
struct f2fs_inode *ri; struct f2fs_inode *ri;
struct extent_tree *et = F2FS_I(inode)->extent_tree; struct extent_tree *et = F2FS_I(inode)->extent_tree;
...@@ -408,7 +425,12 @@ void update_inode(struct inode *inode, struct page *node_page) ...@@ -408,7 +425,12 @@ void update_inode(struct inode *inode, struct page *node_page)
ri->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec); ri->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);
ri->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec); ri->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
ri->i_mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec); ri->i_mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec);
ri->i_current_depth = cpu_to_le32(F2FS_I(inode)->i_current_depth); if (S_ISDIR(inode->i_mode))
ri->i_current_depth =
cpu_to_le32(F2FS_I(inode)->i_current_depth);
else if (S_ISREG(inode->i_mode))
ri->i_gc_failures =
cpu_to_le16(F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN]);
ri->i_xattr_nid = cpu_to_le32(F2FS_I(inode)->i_xattr_nid); ri->i_xattr_nid = cpu_to_le32(F2FS_I(inode)->i_xattr_nid);
ri->i_flags = cpu_to_le32(F2FS_I(inode)->i_flags); ri->i_flags = cpu_to_le32(F2FS_I(inode)->i_flags);
ri->i_pino = cpu_to_le32(F2FS_I(inode)->i_pino); ri->i_pino = cpu_to_le32(F2FS_I(inode)->i_pino);
...@@ -454,12 +476,12 @@ void update_inode(struct inode *inode, struct page *node_page) ...@@ -454,12 +476,12 @@ void update_inode(struct inode *inode, struct page *node_page)
F2FS_I(inode)->i_disk_time[3] = F2FS_I(inode)->i_crtime; F2FS_I(inode)->i_disk_time[3] = F2FS_I(inode)->i_crtime;
} }
void update_inode_page(struct inode *inode) void f2fs_update_inode_page(struct inode *inode)
{ {
struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct page *node_page; struct page *node_page;
retry: retry:
node_page = get_node_page(sbi, inode->i_ino); node_page = f2fs_get_node_page(sbi, inode->i_ino);
if (IS_ERR(node_page)) { if (IS_ERR(node_page)) {
int err = PTR_ERR(node_page); int err = PTR_ERR(node_page);
if (err == -ENOMEM) { if (err == -ENOMEM) {
...@@ -470,7 +492,7 @@ void update_inode_page(struct inode *inode) ...@@ -470,7 +492,7 @@ void update_inode_page(struct inode *inode)
} }
return; return;
} }
update_inode(inode, node_page); f2fs_update_inode(inode, node_page);
f2fs_put_page(node_page, 1); f2fs_put_page(node_page, 1);
} }
...@@ -489,7 +511,7 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) ...@@ -489,7 +511,7 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
* We need to balance fs here to prevent from producing dirty node pages * We need to balance fs here to prevent from producing dirty node pages
* during the urgent cleaning time when runing out of free sections. * during the urgent cleaning time when runing out of free sections.
*/ */
update_inode_page(inode); f2fs_update_inode_page(inode);
if (wbc && wbc->nr_to_write) if (wbc && wbc->nr_to_write)
f2fs_balance_fs(sbi, true); f2fs_balance_fs(sbi, true);
return 0; return 0;
...@@ -506,7 +528,7 @@ void f2fs_evict_inode(struct inode *inode) ...@@ -506,7 +528,7 @@ void f2fs_evict_inode(struct inode *inode)
/* some remained atomic pages should discarded */ /* some remained atomic pages should discarded */
if (f2fs_is_atomic_file(inode)) if (f2fs_is_atomic_file(inode))
drop_inmem_pages(inode); f2fs_drop_inmem_pages(inode);
trace_f2fs_evict_inode(inode); trace_f2fs_evict_inode(inode);
truncate_inode_pages_final(&inode->i_data); truncate_inode_pages_final(&inode->i_data);
...@@ -516,7 +538,7 @@ void f2fs_evict_inode(struct inode *inode) ...@@ -516,7 +538,7 @@ void f2fs_evict_inode(struct inode *inode)
goto out_clear; goto out_clear;
f2fs_bug_on(sbi, get_dirty_pages(inode)); f2fs_bug_on(sbi, get_dirty_pages(inode));
remove_dirty_inode(inode); f2fs_remove_dirty_inode(inode);
f2fs_destroy_extent_tree(inode); f2fs_destroy_extent_tree(inode);
...@@ -525,9 +547,9 @@ void f2fs_evict_inode(struct inode *inode) ...@@ -525,9 +547,9 @@ void f2fs_evict_inode(struct inode *inode)
dquot_initialize(inode); dquot_initialize(inode);
remove_ino_entry(sbi, inode->i_ino, APPEND_INO); f2fs_remove_ino_entry(sbi, inode->i_ino, APPEND_INO);
remove_ino_entry(sbi, inode->i_ino, UPDATE_INO); f2fs_remove_ino_entry(sbi, inode->i_ino, UPDATE_INO);
remove_ino_entry(sbi, inode->i_ino, FLUSH_INO); f2fs_remove_ino_entry(sbi, inode->i_ino, FLUSH_INO);
sb_start_intwrite(inode->i_sb); sb_start_intwrite(inode->i_sb);
set_inode_flag(inode, FI_NO_ALLOC); set_inode_flag(inode, FI_NO_ALLOC);
...@@ -544,7 +566,7 @@ void f2fs_evict_inode(struct inode *inode) ...@@ -544,7 +566,7 @@ void f2fs_evict_inode(struct inode *inode)
#endif #endif
if (!err) { if (!err) {
f2fs_lock_op(sbi); f2fs_lock_op(sbi);
err = remove_inode_page(inode); err = f2fs_remove_inode_page(inode);
f2fs_unlock_op(sbi); f2fs_unlock_op(sbi);
if (err == -ENOENT) if (err == -ENOENT)
err = 0; err = 0;
...@@ -557,7 +579,7 @@ void f2fs_evict_inode(struct inode *inode) ...@@ -557,7 +579,7 @@ void f2fs_evict_inode(struct inode *inode)
} }
if (err) if (err)
update_inode_page(inode); f2fs_update_inode_page(inode);
dquot_free_inode(inode); dquot_free_inode(inode);
sb_end_intwrite(inode->i_sb); sb_end_intwrite(inode->i_sb);
no_delete: no_delete:
...@@ -580,16 +602,19 @@ void f2fs_evict_inode(struct inode *inode) ...@@ -580,16 +602,19 @@ void f2fs_evict_inode(struct inode *inode)
invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid); invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid);
if (inode->i_nlink) { if (inode->i_nlink) {
if (is_inode_flag_set(inode, FI_APPEND_WRITE)) if (is_inode_flag_set(inode, FI_APPEND_WRITE))
add_ino_entry(sbi, inode->i_ino, APPEND_INO); f2fs_add_ino_entry(sbi, inode->i_ino, APPEND_INO);
if (is_inode_flag_set(inode, FI_UPDATE_WRITE)) if (is_inode_flag_set(inode, FI_UPDATE_WRITE))
add_ino_entry(sbi, inode->i_ino, UPDATE_INO); f2fs_add_ino_entry(sbi, inode->i_ino, UPDATE_INO);
} }
if (is_inode_flag_set(inode, FI_FREE_NID)) { if (is_inode_flag_set(inode, FI_FREE_NID)) {
alloc_nid_failed(sbi, inode->i_ino); f2fs_alloc_nid_failed(sbi, inode->i_ino);
clear_inode_flag(inode, FI_FREE_NID); clear_inode_flag(inode, FI_FREE_NID);
} else { } else {
f2fs_bug_on(sbi, err && /*
!exist_written_data(sbi, inode->i_ino, ORPHAN_INO)); * If xattr nid is corrupted, we can reach out error condition,
* err & !f2fs_exist_written_data(sbi, inode->i_ino, ORPHAN_INO)).
* In that case, f2fs_check_nid_range() is enough to give a clue.
*/
} }
out_clear: out_clear:
fscrypt_put_encryption_info(inode); fscrypt_put_encryption_info(inode);
...@@ -597,7 +622,7 @@ void f2fs_evict_inode(struct inode *inode) ...@@ -597,7 +622,7 @@ void f2fs_evict_inode(struct inode *inode)
} }
/* caller should call f2fs_lock_op() */ /* caller should call f2fs_lock_op() */
void handle_failed_inode(struct inode *inode) void f2fs_handle_failed_inode(struct inode *inode)
{ {
struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct node_info ni; struct node_info ni;
...@@ -612,7 +637,7 @@ void handle_failed_inode(struct inode *inode) ...@@ -612,7 +637,7 @@ void handle_failed_inode(struct inode *inode)
* we must call this to avoid inode being remained as dirty, resulting * we must call this to avoid inode being remained as dirty, resulting
* in a panic when flushing dirty inodes in gdirty_list. * in a panic when flushing dirty inodes in gdirty_list.
*/ */
update_inode_page(inode); f2fs_update_inode_page(inode);
f2fs_inode_synced(inode); f2fs_inode_synced(inode);
/* don't make bad inode, since it becomes a regular file. */ /* don't make bad inode, since it becomes a regular file. */
...@@ -623,18 +648,18 @@ void handle_failed_inode(struct inode *inode) ...@@ -623,18 +648,18 @@ void handle_failed_inode(struct inode *inode)
* so we can prevent losing this orphan when encoutering checkpoint * so we can prevent losing this orphan when encoutering checkpoint
* and following suddenly power-off. * and following suddenly power-off.
*/ */
get_node_info(sbi, inode->i_ino, &ni); f2fs_get_node_info(sbi, inode->i_ino, &ni);
if (ni.blk_addr != NULL_ADDR) { if (ni.blk_addr != NULL_ADDR) {
int err = acquire_orphan_inode(sbi); int err = f2fs_acquire_orphan_inode(sbi);
if (err) { if (err) {
set_sbi_flag(sbi, SBI_NEED_FSCK); set_sbi_flag(sbi, SBI_NEED_FSCK);
f2fs_msg(sbi->sb, KERN_WARNING, f2fs_msg(sbi->sb, KERN_WARNING,
"Too many orphan inodes, run fsck to fix."); "Too many orphan inodes, run fsck to fix.");
} else { } else {
add_orphan_inode(inode); f2fs_add_orphan_inode(inode);
} }
alloc_nid_done(sbi, inode->i_ino); f2fs_alloc_nid_done(sbi, inode->i_ino);
} else { } else {
set_inode_flag(inode, FI_FREE_NID); set_inode_flag(inode, FI_FREE_NID);
} }
......
...@@ -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);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -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))
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
新手
引导
客服 返回
顶部