Skip to content

Commit

Permalink
Merge branch 'upstream-f2fs-stable-linux-4.9.y' of https://android.go…
Browse files Browse the repository at this point in the history
…oglesource.com/kernel/common into rebase-sdx-10

* 'upstream-f2fs-stable-linux-4.9.y' of https://android.googlesource.com/kernel/common:
  f2fs: stop GC when the victim becomes fully valid
  f2fs: expose main_blkaddr in sysfs
  f2fs: choose hardlimit when softlimit is larger than hardlimit in f2fs_statfs_project()
  f2fs: Fix deadlock in f2fs_gc() context during atomic files handling
  f2fs: show f2fs instance in printk_ratelimited
  f2fs: fix potential overflow
  f2fs: fix to update dir's i_pino during cross_rename
  f2fs: support aligned pinned file
  f2fs: avoid kernel panic on corruption test
  f2fs: fix wrong description in document
  f2fs: cache global IPU bio
  f2fs: fix to avoid memory leakage in f2fs_listxattr
  f2fs: check total_segments from devices in raw_super
  f2fs: update multi-dev metadata in resize_fs
  f2fs: mark recovery flag correctly in read_raw_super_block()
  f2fs: fix to update time in lazytime mode
  vfs: don't allow writes to swap files
  mm: set S_SWAPFILE on blockdev swap devices
  • Loading branch information
raphielscape committed Jan 15, 2020
2 parents 69e0b7d + f2229c4 commit 84d6637
Show file tree
Hide file tree
Showing 23 changed files with 460 additions and 120 deletions.
6 changes: 6 additions & 0 deletions Documentation/ABI/testing/sysfs-fs-f2fs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ Contact: "Jaegeuk Kim" <jaegeuk.kim@samsung.com>
Description:
Controls the issue rate of segment discard commands.

What: /sys/fs/f2fs/<disk>/max_blkaddr
Date: November 2019
Contact: "Ramon Pantin" <pantin@google.com>
Description:
Shows first block address of MAIN area.

What: /sys/fs/f2fs/<disk>/ipu_policy
Date: November 2013
Contact: "Jaegeuk Kim" <jaegeuk.kim@samsung.com>
Expand Down
5 changes: 4 additions & 1 deletion Documentation/filesystems/f2fs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ Files in /sys/fs/f2fs/<devname>
reclaim the prefree segments to free segments.
By default, 5% over total # of segments.

main_blkaddr This value gives the first block address of
MAIN area in the partition.

max_small_discards This parameter controls the number of discard
commands that consist small blocks less than 2MB.
The candidates to be discarded are cached until
Expand Down Expand Up @@ -346,7 +349,7 @@ Files in /sys/fs/f2fs/<devname>

ram_thresh This parameter controls the memory footprint used
by free nids and cached nat entries. By default,
10 is set, which indicates 10 MB / 1 GB RAM.
1 is set, which indicates 10 MB / 1 GB RAM.

ra_nid_pages When building free nids, F2FS reads NAT blocks
ahead for speed up. Default is 0.
Expand Down
3 changes: 3 additions & 0 deletions fs/block_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1742,6 +1742,9 @@ ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from)
if (bdev_read_only(I_BDEV(bd_inode)))
return -EPERM;

if (IS_SWAPFILE(bd_inode))
return -ETXTBSY;

if (!iov_iter_count(from))
return 0;

Expand Down
2 changes: 1 addition & 1 deletion fs/f2fs/checkpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ int f2fs_acquire_orphan_inode(struct f2fs_sb_info *sbi)

if (time_to_inject(sbi, FAULT_ORPHAN)) {
spin_unlock(&im->ino_lock);
f2fs_show_injection_info(FAULT_ORPHAN);
f2fs_show_injection_info(sbi, FAULT_ORPHAN);
return -ENOSPC;
}

Expand Down
189 changes: 153 additions & 36 deletions fs/f2fs/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#define NUM_PREALLOC_POST_READ_CTXS 128

static struct kmem_cache *bio_post_read_ctx_cache;
static struct kmem_cache *bio_entry_slab;
static mempool_t *bio_post_read_ctx_pool;

static bool __is_cp_guaranteed(struct page *page)
Expand Down Expand Up @@ -145,8 +146,10 @@ static void f2fs_read_end_io(struct bio *bio)
{
struct page *first_page = bio->bi_io_vec[0].bv_page;

if (time_to_inject(F2FS_P_SB(bio->bi_io_vec->bv_page), FAULT_READ_IO)) {
f2fs_show_injection_info(FAULT_READ_IO);
struct f2fs_sb_info *sbi = F2FS_P_SB(bio->bi_io_vec->bv_page);

if (time_to_inject(sbi, FAULT_READ_IO)) {
f2fs_show_injection_info(sbi, FAULT_READ_IO);
bio->bi_error = -EIO;
}

Expand Down Expand Up @@ -175,7 +178,7 @@ static void f2fs_write_end_io(struct bio *bio)
int i;

if (time_to_inject(sbi, FAULT_WRITE_IO)) {
f2fs_show_injection_info(FAULT_WRITE_IO);
f2fs_show_injection_info(sbi, FAULT_WRITE_IO);
bio->bi_error = -EIO;
}

Expand Down Expand Up @@ -559,6 +562,126 @@ static bool io_is_mergeable(struct f2fs_sb_info *sbi, struct bio *bio,
return io_type_is_mergeable(io, fio);
}

static void add_bio_entry(struct f2fs_sb_info *sbi, struct bio *bio,
struct page *page, enum temp_type temp)
{
struct f2fs_bio_info *io = sbi->write_io[DATA] + temp;
struct bio_entry *be;

be = f2fs_kmem_cache_alloc(bio_entry_slab, GFP_NOFS);
be->bio = bio;
bio_get(bio);

if (bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE)
f2fs_bug_on(sbi, 1);

down_write(&io->bio_list_lock);
list_add_tail(&be->list, &io->bio_list);
up_write(&io->bio_list_lock);
}

static void del_bio_entry(struct bio_entry *be)
{
list_del(&be->list);
kmem_cache_free(bio_entry_slab, be);
}

static int add_ipu_page(struct f2fs_sb_info *sbi, struct bio **bio,
struct page *page)
{
enum temp_type temp;
bool found = false;
int ret = -EAGAIN;

for (temp = HOT; temp < NR_TEMP_TYPE && !found; temp++) {
struct f2fs_bio_info *io = sbi->write_io[DATA] + temp;
struct list_head *head = &io->bio_list;
struct bio_entry *be;

down_write(&io->bio_list_lock);
list_for_each_entry(be, head, list) {
if (be->bio != *bio)
continue;

found = true;

if (bio_add_page(*bio, page, PAGE_SIZE, 0) == PAGE_SIZE) {
ret = 0;
break;
}

/* bio is full */
del_bio_entry(be);
__submit_bio(sbi, *bio, DATA);
break;
}
up_write(&io->bio_list_lock);
}

if (ret) {
bio_put(*bio);
*bio = NULL;
}

return ret;
}

void f2fs_submit_merged_ipu_write(struct f2fs_sb_info *sbi,
struct bio **bio, struct page *page)
{
enum temp_type temp;
bool found = false;
struct bio *target = bio ? *bio : NULL;

for (temp = HOT; temp < NR_TEMP_TYPE && !found; temp++) {
struct f2fs_bio_info *io = sbi->write_io[DATA] + temp;
struct list_head *head = &io->bio_list;
struct bio_entry *be;

if (list_empty(head))
continue;

down_read(&io->bio_list_lock);
list_for_each_entry(be, head, list) {
if (target)
found = (target == be->bio);
else
found = __has_merged_page(be->bio, NULL,
page, 0);
if (found)
break;
}
up_read(&io->bio_list_lock);

if (!found)
continue;

found = false;

down_write(&io->bio_list_lock);
list_for_each_entry(be, head, list) {
if (target)
found = (target == be->bio);
else
found = __has_merged_page(be->bio, NULL,
page, 0);
if (found) {
target = be->bio;
del_bio_entry(be);
break;
}
}
up_write(&io->bio_list_lock);
}

if (found)
__submit_bio(sbi, target, DATA);
if (bio && *bio) {
bio_put(*bio);
*bio = NULL;
}
}

int f2fs_merge_page_bio(struct f2fs_io_info *fio)
{
struct bio *bio = *fio->bio;
Expand All @@ -573,20 +696,17 @@ int f2fs_merge_page_bio(struct f2fs_io_info *fio)
f2fs_trace_ios(fio, 0);

if (bio && !page_is_mergeable(fio->sbi, bio, *fio->last_block,
fio->new_blkaddr)) {
__submit_bio(fio->sbi, bio, fio->type);
bio = NULL;
}
fio->new_blkaddr))
f2fs_submit_merged_ipu_write(fio->sbi, &bio, NULL);
alloc_new:
if (!bio) {
bio = __bio_alloc(fio, BIO_MAX_PAGES);
bio_set_op_attrs(bio, fio->op, fio->op_flags);
}

if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
__submit_bio(fio->sbi, bio, fio->type);
bio = NULL;
goto alloc_new;
add_bio_entry(fio->sbi, bio, page, fio->temp);
} else {
if (add_ipu_page(fio->sbi, &bio, page))
goto alloc_new;
}

if (fio->io_wbc)
Expand All @@ -600,19 +720,6 @@ int f2fs_merge_page_bio(struct f2fs_io_info *fio)
return 0;
}

static void f2fs_submit_ipu_bio(struct f2fs_sb_info *sbi, struct bio **bio,
struct page *page)
{
if (!bio)
return;

if (!__has_merged_page(*bio, NULL, page, 0))
return;

__submit_bio(sbi, *bio, DATA);
*bio = NULL;
}

void f2fs_submit_page_write(struct f2fs_io_info *fio)
{
struct f2fs_sb_info *sbi = fio->sbi;
Expand Down Expand Up @@ -2130,7 +2237,7 @@ static int __write_data_page(struct page *page, bool *submitted,
loff_t i_size = i_size_read(inode);
const pgoff_t end_index = ((unsigned long long) i_size)
>> PAGE_SHIFT;
loff_t psize = (page->index + 1) << PAGE_SHIFT;
loff_t psize = (loff_t)(page->index + 1) << PAGE_SHIFT;
unsigned offset = 0;
bool need_balance_fs = false;
int err = 0;
Expand Down Expand Up @@ -2247,14 +2354,12 @@ static int __write_data_page(struct page *page, bool *submitted,

unlock_page(page);
if (!S_ISDIR(inode->i_mode) && !IS_NOQUOTA(inode) &&
!F2FS_I(inode)->cp_task) {
f2fs_submit_ipu_bio(sbi, bio, page);
!F2FS_I(inode)->cp_task)
f2fs_balance_fs(sbi, need_balance_fs);
}

if (unlikely(f2fs_cp_error(sbi))) {
f2fs_submit_ipu_bio(sbi, bio, page);
f2fs_submit_merged_write(sbi, DATA);
f2fs_submit_merged_ipu_write(sbi, bio, NULL);
submitted = NULL;
}

Expand Down Expand Up @@ -2374,13 +2479,11 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
}

if (PageWriteback(page)) {
if (wbc->sync_mode != WB_SYNC_NONE) {
if (wbc->sync_mode != WB_SYNC_NONE)
f2fs_wait_on_page_writeback(page,
DATA, true, true);
f2fs_submit_ipu_bio(sbi, &bio, page);
} else {
else
goto continue_unlock;
}
}

if (!clear_page_dirty_for_io(page))
Expand Down Expand Up @@ -2438,7 +2541,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
NULL, 0, DATA);
/* submit cached bio of IPU write */
if (bio)
__submit_bio(sbi, bio, DATA);
f2fs_submit_merged_ipu_write(sbi, &bio, NULL);

return ret;
}
Expand Down Expand Up @@ -3273,8 +3376,22 @@ int __init f2fs_init_post_read_processing(void)
return -ENOMEM;
}

void __exit f2fs_destroy_post_read_processing(void)
void f2fs_destroy_post_read_processing(void)
{
mempool_destroy(bio_post_read_ctx_pool);
kmem_cache_destroy(bio_post_read_ctx_cache);
}

int __init f2fs_init_bio_entry_cache(void)
{
bio_entry_slab = f2fs_kmem_cache_create("bio_entry_slab",
sizeof(struct bio_entry));
if (!bio_entry_slab)
return -ENOMEM;
return 0;
}

void __exit f2fs_destroy_bio_entry_cache(void)
{
kmem_cache_destroy(bio_entry_slab);
}
7 changes: 4 additions & 3 deletions fs/f2fs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ int f2fs_add_regular_entry(struct inode *dir, const struct qstr *new_name,

start:
if (time_to_inject(F2FS_I_SB(dir), FAULT_DIR_DEPTH)) {
f2fs_show_injection_info(FAULT_DIR_DEPTH);
f2fs_show_injection_info(F2FS_I_SB(dir), FAULT_DIR_DEPTH);
return -ENOSPC;
}

Expand Down Expand Up @@ -805,8 +805,9 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
bit_pos++;
ctx->pos = start_pos + bit_pos;
printk_ratelimited(
"%s, invalid namelen(0), ino:%u, run fsck to fix.",
KERN_WARNING, le32_to_cpu(de->ino));
"%sF2FS-fs (%s): invalid namelen(0), ino:%u, run fsck to fix.",
KERN_WARNING, sbi->sb->s_id,
le32_to_cpu(de->ino));
set_sbi_flag(sbi, SBI_NEED_FSCK);
continue;
}
Expand Down
Loading

0 comments on commit 84d6637

Please sign in to comment.