From: Linus Torvalds Date: Wed, 27 Jul 2016 17:36:31 +0000 (-0700) Subject: Merge tag 'for-f2fs-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk... X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=4fc29c1aa375;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git Merge tag 'for-f2fs-4.8' of git://git./linux/kernel/git/jaegeuk/f2fs Pull f2fs updates from Jaegeuk Kim: "The major change in this version is mitigating cpu overheads on write paths by replacing redundant inode page updates with mark_inode_dirty calls. And we tried to reduce lock contentions as well to improve filesystem scalability. Other feature is setting F2FS automatically when detecting host-managed SMR. Enhancements: - ioctl to move a range of data between files - inject orphan inode errors - avoid flush commands congestion - support lazytime Bug fixes: - return proper results for some dentry operations - fix deadlock in add_link failure - disable extent_cache for fcollapse/finsert" * tag 'for-f2fs-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (68 commits) f2fs: clean up coding style and redundancy f2fs: get victim segment again after new cp f2fs: handle error case with f2fs_bug_on f2fs: avoid data race when deciding checkpoin in f2fs_sync_file f2fs: support an ioctl to move a range of data blocks f2fs: fix to report error number of f2fs_find_entry f2fs: avoid memory allocation failure due to a long length f2fs: reset default idle interval value f2fs: use blk_plug in all the possible paths f2fs: fix to avoid data update racing between GC and DIO f2fs: add maximum prefree segments f2fs: disable extent_cache for fcollapse/finsert inodes f2fs: refactor __exchange_data_block for speed up f2fs: fix ERR_PTR returned by bio f2fs: avoid mark_inode_dirty f2fs: move i_size_write in f2fs_write_end f2fs: fix to avoid redundant discard during fstrim f2fs: avoid mismatching block range for discard f2fs: fix incorrect f_bfree calculation in ->statfs f2fs: use percpu_rw_semaphore ... --- 4fc29c1aa375353ffe7c8fa171bf941b71ce29ef diff --cc fs/f2fs/data.c index ded224518978,614154f9bb35..e2624275d828 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@@ -97,11 -100,16 +100,16 @@@ static struct bio *__bio_alloc(struct f return bio; } - static inline void __submit_bio(struct f2fs_sb_info *sbi, struct bio *bio) -static inline void __submit_bio(struct f2fs_sb_info *sbi, int rw, - struct bio *bio, enum page_type type) ++static inline void __submit_bio(struct f2fs_sb_info *sbi, ++ struct bio *bio, enum page_type type) { - if (!is_read_io(bio_op(bio))) - if (!is_read_io(rw)) { ++ if (!is_read_io(bio_op(bio))) { atomic_inc(&sbi->nr_wb_bios); + if (f2fs_sb_mounted_hmsmr(sbi->sb) && + current->plug && (type == DATA || type == NODE)) + blk_finish_plug(current->plug); + } - submit_bio(rw, bio); + submit_bio(bio); } static void __submit_merged_bio(struct f2fs_bio_info *io) @@@ -116,9 -124,7 +124,9 @@@ else trace_f2fs_submit_write_bio(io->sbi->sb, fio, io->bio); - __submit_bio(io->sbi, fio->rw, io->bio, fio->type); + bio_set_op_attrs(io->bio, fio->op, fio->op_flags); + - __submit_bio(io->sbi, io->bio); ++ __submit_bio(io->sbi, io->bio, fio->type); io->bio = NULL; } @@@ -237,10 -241,8 +245,10 @@@ int f2fs_submit_page_bio(struct f2fs_io bio_put(bio); return -EFAULT; } + bio->bi_rw = fio->op_flags; + bio_set_op_attrs(bio, fio->op, fio->op_flags); - __submit_bio(fio->sbi, bio); - __submit_bio(fio->sbi, fio->rw, bio, fio->type); ++ __submit_bio(fio->sbi, bio, fio->type); return 0; } @@@ -1058,36 -1080,15 +1088,16 @@@ got_it */ if (bio && (last_block_in_bio != block_nr - 1)) { submit_and_realloc: - __submit_bio(F2FS_I_SB(inode), bio); - __submit_bio(F2FS_I_SB(inode), READ, bio, DATA); ++ __submit_bio(F2FS_I_SB(inode), bio, DATA); bio = NULL; } if (bio == NULL) { - struct fscrypt_ctx *ctx = NULL; - - if (f2fs_encrypted_inode(inode) && - S_ISREG(inode->i_mode)) { - - ctx = fscrypt_get_ctx(inode, GFP_NOFS); - if (IS_ERR(ctx)) - goto set_error_page; - - /* wait the page to be moved by cleaning */ - f2fs_wait_on_encrypted_page_writeback( - F2FS_I_SB(inode), block_nr); - } - - bio = bio_alloc(GFP_KERNEL, - min_t(int, nr_pages, BIO_MAX_PAGES)); - if (!bio) { - if (ctx) - fscrypt_release_ctx(ctx); + bio = f2fs_grab_bio(inode, block_nr, nr_pages); + if (IS_ERR(bio)) { + bio = NULL; goto set_error_page; } - bio->bi_bdev = bdev; - bio->bi_iter.bi_sector = SECTOR_FROM_BLOCK(block_nr); - bio->bi_end_io = f2fs_read_end_io; - bio->bi_private = ctx; + bio_set_op_attrs(bio, REQ_OP_READ, 0); } if (bio_add_page(bio, page, blocksize, 0) < blocksize) @@@ -1102,7 -1103,7 +1112,7 @@@ set_error_page goto next_page; confused: if (bio) { - __submit_bio(F2FS_I_SB(inode), bio); - __submit_bio(F2FS_I_SB(inode), READ, bio, DATA); ++ __submit_bio(F2FS_I_SB(inode), bio, DATA); bio = NULL; } unlock_page(page); @@@ -1112,7 -1113,7 +1122,7 @@@ next_page } BUG_ON(pages && !list_empty(pages)); if (bio) - __submit_bio(F2FS_I_SB(inode), bio); - __submit_bio(F2FS_I_SB(inode), READ, bio, DATA); ++ __submit_bio(F2FS_I_SB(inode), bio, DATA); return 0; } @@@ -1668,25 -1641,23 +1651,23 @@@ repeat if (blkaddr == NEW_ADDR) { zero_user_segment(page, 0, PAGE_SIZE); } else { - struct f2fs_io_info fio = { - .sbi = sbi, - .type = DATA, - .op = REQ_OP_READ, - .op_flags = READ_SYNC, - .old_blkaddr = blkaddr, - .new_blkaddr = blkaddr, - .page = page, - .encrypted_page = NULL, - }; - err = f2fs_submit_page_bio(&fio); - if (err) - goto fail; + struct bio *bio; - lock_page(page); - if (unlikely(!PageUptodate(page))) { - err = -EIO; + bio = f2fs_grab_bio(inode, blkaddr, 1); + if (IS_ERR(bio)) { + err = PTR_ERR(bio); goto fail; } - ++ bio_set_op_attrs(bio, REQ_OP_READ, READ_SYNC); + if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) { + bio_put(bio); + err = -EFAULT; + goto fail; + } + - __submit_bio(sbi, READ_SYNC, bio, DATA); ++ __submit_bio(sbi, bio, DATA); + + lock_page(page); if (unlikely(page->mapping != mapping)) { f2fs_put_page(page, 1); goto repeat; diff --cc fs/f2fs/segment.c index 4c2d1fa1e0e2,d45e6bbf8493..a46296f57b02 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@@ -439,9 -444,10 +446,11 @@@ int f2fs_issue_flush(struct f2fs_sb_inf struct bio *bio = f2fs_bio_alloc(0); int ret; + atomic_inc(&fcc->submit_flush); bio->bi_bdev = sbi->sb->s_bdev; - ret = submit_bio_wait(WRITE_FLUSH, bio); + bio_set_op_attrs(bio, REQ_OP_WRITE, WRITE_FLUSH); + ret = submit_bio_wait(bio); + atomic_dec(&fcc->submit_flush); bio_put(bio); return ret; }