Merge tag 'for-f2fs-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 27 Jul 2016 17:36:31 +0000 (10:36 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 27 Jul 2016 17:36:31 +0000 (10:36 -0700)
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
  ...

1  2 
fs/f2fs/checkpoint.c
fs/f2fs/data.c
fs/f2fs/f2fs.h
fs/f2fs/gc.c
fs/f2fs/inline.c
fs/f2fs/node.c
fs/f2fs/segment.c

Simple merge
diff --cc fs/f2fs/data.c
index ded224518978355821c2345d07c88d71b885aa74,614154f9bb3533f60f935e2d57426391d08895b4..e2624275d828c5d65885948e6426e8906e305a90
@@@ -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);
 -      submit_bio(rw, bio);
+               if (f2fs_sb_mounted_hmsmr(sbi->sb) &&
+                       current->plug && (type == DATA || type == NODE))
+                       blk_finish_plug(current->plug);
+       }
 +      submit_bio(bio);
  }
  
  static void __submit_merged_bio(struct f2fs_bio_info *io)
        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/f2fs.h
Simple merge
diff --cc fs/f2fs/gc.c
Simple merge
Simple merge
diff --cc fs/f2fs/node.c
Simple merge
index 4c2d1fa1e0e2e9e581b09397da28e0e8a54e4d32,d45e6bbf84934332e1f975a95868137017844a17..a46296f57b026e650f2a82950ae7f63a02fd2fb0
@@@ -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;
        }