1. 02 8月, 2018 2 次提交
    • C
      f2fs: fix to propagate error from __get_meta_page() · 7735730d
      Chao Yu 提交于
      If caller of __get_meta_page() can handle error, let's propagate error
      from __get_meta_page().
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      7735730d
    • C
      f2fs: fix to do sanity check with block address in main area · c9b60788
      Chao Yu 提交于
      This patch add to do sanity check with below field:
      - cp_pack_total_block_count
      - blkaddr of data/node
      - extent info
      
      - Overview
      BUG() in verify_block_addr() when writing to a corrupted f2fs image
      
      - Reproduce (4.18 upstream kernel)
      
      - POC (poc.c)
      
      static void activity(char *mpoint) {
      
        char *foo_bar_baz;
        int err;
      
        static int buf[8192];
        memset(buf, 0, sizeof(buf));
      
        err = asprintf(&foo_bar_baz, "%s/foo/bar/baz", mpoint);
      
        int fd = open(foo_bar_baz, O_RDWR | O_TRUNC, 0777);
        if (fd >= 0) {
          write(fd, (char *)buf, sizeof(buf));
          fdatasync(fd);
          close(fd);
        }
      }
      
      int main(int argc, char *argv[]) {
        activity(argv[1]);
        return 0;
      }
      
      - Kernel message
      [  689.349473] F2FS-fs (loop0): Mounted with checkpoint version = 3
      [  699.728662] WARNING: CPU: 0 PID: 1309 at fs/f2fs/segment.c:2860 f2fs_inplace_write_data+0x232/0x240
      [  699.728670] Modules linked in: snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd mac_hid i2c_piix4 soundcore ib_iser rdma_cm iw_cm ib_cm ib_core iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx raid1 raid0 multipath linear 8139too crct10dif_pclmul crc32_pclmul qxl drm_kms_helper syscopyarea aesni_intel sysfillrect sysimgblt fb_sys_fops ttm drm aes_x86_64 crypto_simd cryptd 8139cp glue_helper mii pata_acpi floppy
      [  699.729056] CPU: 0 PID: 1309 Comm: a.out Not tainted 4.18.0-rc1+ #4
      [  699.729064] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
      [  699.729074] RIP: 0010:f2fs_inplace_write_data+0x232/0x240
      [  699.729076] Code: ff e9 cf fe ff ff 49 8d 7d 10 e8 39 45 ad ff 4d 8b 7d 10 be 04 00 00 00 49 8d 7f 48 e8 07 49 ad ff 45 8b 7f 48 e9 fb fe ff ff <0f> 0b f0 41 80 4d 48 04 e9 65 fe ff ff 90 66 66 66 66 90 55 48 8d
      [  699.729130] RSP: 0018:ffff8801f43af568 EFLAGS: 00010202
      [  699.729139] RAX: 000000000000003f RBX: ffff8801f43af7b8 RCX: ffffffffb88c9113
      [  699.729142] RDX: 0000000000000003 RSI: dffffc0000000000 RDI: ffff8802024e5540
      [  699.729144] RBP: ffff8801f43af590 R08: 0000000000000009 R09: ffffffffffffffe8
      [  699.729147] R10: 0000000000000001 R11: ffffed0039b0596a R12: ffff8802024e5540
      [  699.729149] R13: ffff8801f0335500 R14: ffff8801e3e7a700 R15: ffff8801e1ee4450
      [  699.729154] FS:  00007f9bf97f5700(0000) GS:ffff8801f6e00000(0000) knlGS:0000000000000000
      [  699.729156] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [  699.729159] CR2: 00007f9bf925d170 CR3: 00000001f0c34000 CR4: 00000000000006f0
      [  699.729171] Call Trace:
      [  699.729192]  f2fs_do_write_data_page+0x2e2/0xe00
      [  699.729203]  ? f2fs_should_update_outplace+0xd0/0xd0
      [  699.729238]  ? memcg_drain_all_list_lrus+0x280/0x280
      [  699.729269]  ? __radix_tree_replace+0xa3/0x120
      [  699.729276]  __write_data_page+0x5c7/0xe30
      [  699.729291]  ? kasan_check_read+0x11/0x20
      [  699.729310]  ? page_mapped+0x8a/0x110
      [  699.729321]  ? page_mkclean+0xe9/0x160
      [  699.729327]  ? f2fs_do_write_data_page+0xe00/0xe00
      [  699.729331]  ? invalid_page_referenced_vma+0x130/0x130
      [  699.729345]  ? clear_page_dirty_for_io+0x332/0x450
      [  699.729351]  f2fs_write_cache_pages+0x4ca/0x860
      [  699.729358]  ? __write_data_page+0xe30/0xe30
      [  699.729374]  ? percpu_counter_add_batch+0x22/0xa0
      [  699.729380]  ? kasan_check_write+0x14/0x20
      [  699.729391]  ? _raw_spin_lock+0x17/0x40
      [  699.729403]  ? f2fs_mark_inode_dirty_sync.part.18+0x16/0x30
      [  699.729413]  ? iov_iter_advance+0x113/0x640
      [  699.729418]  ? f2fs_write_end+0x133/0x2e0
      [  699.729423]  ? balance_dirty_pages_ratelimited+0x239/0x640
      [  699.729428]  f2fs_write_data_pages+0x329/0x520
      [  699.729433]  ? generic_perform_write+0x250/0x320
      [  699.729438]  ? f2fs_write_cache_pages+0x860/0x860
      [  699.729454]  ? current_time+0x110/0x110
      [  699.729459]  ? f2fs_preallocate_blocks+0x1ef/0x370
      [  699.729464]  do_writepages+0x37/0xb0
      [  699.729468]  ? f2fs_write_cache_pages+0x860/0x860
      [  699.729472]  ? do_writepages+0x37/0xb0
      [  699.729478]  __filemap_fdatawrite_range+0x19a/0x1f0
      [  699.729483]  ? delete_from_page_cache_batch+0x4e0/0x4e0
      [  699.729496]  ? __vfs_write+0x2b2/0x410
      [  699.729501]  file_write_and_wait_range+0x66/0xb0
      [  699.729506]  f2fs_do_sync_file+0x1f9/0xd90
      [  699.729511]  ? truncate_partial_data_page+0x290/0x290
      [  699.729521]  ? __sb_end_write+0x30/0x50
      [  699.729526]  ? vfs_write+0x20f/0x260
      [  699.729530]  f2fs_sync_file+0x9a/0xb0
      [  699.729534]  ? f2fs_do_sync_file+0xd90/0xd90
      [  699.729548]  vfs_fsync_range+0x68/0x100
      [  699.729554]  ? __fget_light+0xc9/0xe0
      [  699.729558]  do_fsync+0x3d/0x70
      [  699.729562]  __x64_sys_fdatasync+0x24/0x30
      [  699.729585]  do_syscall_64+0x78/0x170
      [  699.729595]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
      [  699.729613] RIP: 0033:0x7f9bf930d800
      [  699.729615] Code: 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 83 3d 49 bf 2c 00 00 75 10 b8 4b 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 be 78 01 00 48 89 04 24
      [  699.729668] RSP: 002b:00007ffee3606c68 EFLAGS: 00000246 ORIG_RAX: 000000000000004b
      [  699.729673] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f9bf930d800
      [  699.729675] RDX: 0000000000008000 RSI: 00000000006010a0 RDI: 0000000000000003
      [  699.729678] RBP: 00007ffee3606ca0 R08: 0000000001503010 R09: 0000000000000000
      [  699.729680] R10: 00000000000002e8 R11: 0000000000000246 R12: 0000000000400610
      [  699.729683] R13: 00007ffee3606da0 R14: 0000000000000000 R15: 0000000000000000
      [  699.729687] ---[ end trace 4ce02f25ff7d3df5 ]---
      [  699.729782] ------------[ cut here ]------------
      [  699.729785] kernel BUG at fs/f2fs/segment.h:654!
      [  699.731055] invalid opcode: 0000 [#1] SMP KASAN PTI
      [  699.732104] CPU: 0 PID: 1309 Comm: a.out Tainted: G        W         4.18.0-rc1+ #4
      [  699.733684] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
      [  699.735611] RIP: 0010:f2fs_submit_page_bio+0x29b/0x730
      [  699.736649] Code: 54 49 8d bd 18 04 00 00 e8 b2 59 af ff 41 8b 8d 18 04 00 00 8b 45 b8 41 d3 e6 44 01 f0 4c 8d 73 14 41 39 c7 0f 82 37 fe ff ff <0f> 0b 65 8b 05 2c 04 77 47 89 c0 48 0f a3 05 52 c1 d5 01 0f 92 c0
      [  699.740524] RSP: 0018:ffff8801f43af508 EFLAGS: 00010283
      [  699.741573] RAX: 0000000000000000 RBX: ffff8801f43af7b8 RCX: ffffffffb88a7cef
      [  699.743006] RDX: 0000000000000007 RSI: dffffc0000000000 RDI: ffff8801e3e7a64c
      [  699.744426] RBP: ffff8801f43af558 R08: ffffed003e066b55 R09: ffffed003e066b55
      [  699.745833] R10: 0000000000000001 R11: ffffed003e066b54 R12: ffffea0007876940
      [  699.747256] R13: ffff8801f0335500 R14: ffff8801e3e7a600 R15: 0000000000000001
      [  699.748683] FS:  00007f9bf97f5700(0000) GS:ffff8801f6e00000(0000) knlGS:0000000000000000
      [  699.750293] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [  699.751462] CR2: 00007f9bf925d170 CR3: 00000001f0c34000 CR4: 00000000000006f0
      [  699.752874] Call Trace:
      [  699.753386]  ? f2fs_inplace_write_data+0x93/0x240
      [  699.754341]  f2fs_inplace_write_data+0xd2/0x240
      [  699.755271]  f2fs_do_write_data_page+0x2e2/0xe00
      [  699.756214]  ? f2fs_should_update_outplace+0xd0/0xd0
      [  699.757215]  ? memcg_drain_all_list_lrus+0x280/0x280
      [  699.758209]  ? __radix_tree_replace+0xa3/0x120
      [  699.759164]  __write_data_page+0x5c7/0xe30
      [  699.760002]  ? kasan_check_read+0x11/0x20
      [  699.760823]  ? page_mapped+0x8a/0x110
      [  699.761573]  ? page_mkclean+0xe9/0x160
      [  699.762345]  ? f2fs_do_write_data_page+0xe00/0xe00
      [  699.763332]  ? invalid_page_referenced_vma+0x130/0x130
      [  699.764374]  ? clear_page_dirty_for_io+0x332/0x450
      [  699.765347]  f2fs_write_cache_pages+0x4ca/0x860
      [  699.766276]  ? __write_data_page+0xe30/0xe30
      [  699.767161]  ? percpu_counter_add_batch+0x22/0xa0
      [  699.768112]  ? kasan_check_write+0x14/0x20
      [  699.768951]  ? _raw_spin_lock+0x17/0x40
      [  699.769739]  ? f2fs_mark_inode_dirty_sync.part.18+0x16/0x30
      [  699.770885]  ? iov_iter_advance+0x113/0x640
      [  699.771743]  ? f2fs_write_end+0x133/0x2e0
      [  699.772569]  ? balance_dirty_pages_ratelimited+0x239/0x640
      [  699.773680]  f2fs_write_data_pages+0x329/0x520
      [  699.774603]  ? generic_perform_write+0x250/0x320
      [  699.775544]  ? f2fs_write_cache_pages+0x860/0x860
      [  699.776510]  ? current_time+0x110/0x110
      [  699.777299]  ? f2fs_preallocate_blocks+0x1ef/0x370
      [  699.778279]  do_writepages+0x37/0xb0
      [  699.779026]  ? f2fs_write_cache_pages+0x860/0x860
      [  699.779978]  ? do_writepages+0x37/0xb0
      [  699.780755]  __filemap_fdatawrite_range+0x19a/0x1f0
      [  699.781746]  ? delete_from_page_cache_batch+0x4e0/0x4e0
      [  699.782820]  ? __vfs_write+0x2b2/0x410
      [  699.783597]  file_write_and_wait_range+0x66/0xb0
      [  699.784540]  f2fs_do_sync_file+0x1f9/0xd90
      [  699.785381]  ? truncate_partial_data_page+0x290/0x290
      [  699.786415]  ? __sb_end_write+0x30/0x50
      [  699.787204]  ? vfs_write+0x20f/0x260
      [  699.787941]  f2fs_sync_file+0x9a/0xb0
      [  699.788694]  ? f2fs_do_sync_file+0xd90/0xd90
      [  699.789572]  vfs_fsync_range+0x68/0x100
      [  699.790360]  ? __fget_light+0xc9/0xe0
      [  699.791128]  do_fsync+0x3d/0x70
      [  699.791779]  __x64_sys_fdatasync+0x24/0x30
      [  699.792614]  do_syscall_64+0x78/0x170
      [  699.793371]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
      [  699.794406] RIP: 0033:0x7f9bf930d800
      [  699.795134] Code: 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 83 3d 49 bf 2c 00 00 75 10 b8 4b 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 be 78 01 00 48 89 04 24
      [  699.798960] RSP: 002b:00007ffee3606c68 EFLAGS: 00000246 ORIG_RAX: 000000000000004b
      [  699.800483] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f9bf930d800
      [  699.801923] RDX: 0000000000008000 RSI: 00000000006010a0 RDI: 0000000000000003
      [  699.803373] RBP: 00007ffee3606ca0 R08: 0000000001503010 R09: 0000000000000000
      [  699.804798] R10: 00000000000002e8 R11: 0000000000000246 R12: 0000000000400610
      [  699.806233] R13: 00007ffee3606da0 R14: 0000000000000000 R15: 0000000000000000
      [  699.807667] Modules linked in: snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd mac_hid i2c_piix4 soundcore ib_iser rdma_cm iw_cm ib_cm ib_core iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx raid1 raid0 multipath linear 8139too crct10dif_pclmul crc32_pclmul qxl drm_kms_helper syscopyarea aesni_intel sysfillrect sysimgblt fb_sys_fops ttm drm aes_x86_64 crypto_simd cryptd 8139cp glue_helper mii pata_acpi floppy
      [  699.817079] ---[ end trace 4ce02f25ff7d3df6 ]---
      [  699.818068] RIP: 0010:f2fs_submit_page_bio+0x29b/0x730
      [  699.819114] Code: 54 49 8d bd 18 04 00 00 e8 b2 59 af ff 41 8b 8d 18 04 00 00 8b 45 b8 41 d3 e6 44 01 f0 4c 8d 73 14 41 39 c7 0f 82 37 fe ff ff <0f> 0b 65 8b 05 2c 04 77 47 89 c0 48 0f a3 05 52 c1 d5 01 0f 92 c0
      [  699.822919] RSP: 0018:ffff8801f43af508 EFLAGS: 00010283
      [  699.823977] RAX: 0000000000000000 RBX: ffff8801f43af7b8 RCX: ffffffffb88a7cef
      [  699.825436] RDX: 0000000000000007 RSI: dffffc0000000000 RDI: ffff8801e3e7a64c
      [  699.826881] RBP: ffff8801f43af558 R08: ffffed003e066b55 R09: ffffed003e066b55
      [  699.828292] R10: 0000000000000001 R11: ffffed003e066b54 R12: ffffea0007876940
      [  699.829750] R13: ffff8801f0335500 R14: ffff8801e3e7a600 R15: 0000000000000001
      [  699.831192] FS:  00007f9bf97f5700(0000) GS:ffff8801f6e00000(0000) knlGS:0000000000000000
      [  699.832793] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [  699.833981] CR2: 00007f9bf925d170 CR3: 00000001f0c34000 CR4: 00000000000006f0
      [  699.835556] ==================================================================
      [  699.837029] BUG: KASAN: stack-out-of-bounds in update_stack_state+0x38c/0x3e0
      [  699.838462] Read of size 8 at addr ffff8801f43af970 by task a.out/1309
      
      [  699.840086] CPU: 0 PID: 1309 Comm: a.out Tainted: G      D W         4.18.0-rc1+ #4
      [  699.841603] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
      [  699.843475] Call Trace:
      [  699.843982]  dump_stack+0x7b/0xb5
      [  699.844661]  print_address_description+0x70/0x290
      [  699.845607]  kasan_report+0x291/0x390
      [  699.846351]  ? update_stack_state+0x38c/0x3e0
      [  699.853831]  __asan_load8+0x54/0x90
      [  699.854569]  update_stack_state+0x38c/0x3e0
      [  699.855428]  ? __read_once_size_nocheck.constprop.7+0x20/0x20
      [  699.856601]  ? __save_stack_trace+0x5e/0x100
      [  699.857476]  unwind_next_frame.part.5+0x18e/0x490
      [  699.858448]  ? unwind_dump+0x290/0x290
      [  699.859217]  ? clear_page_dirty_for_io+0x332/0x450
      [  699.860185]  __unwind_start+0x106/0x190
      [  699.860974]  __save_stack_trace+0x5e/0x100
      [  699.861808]  ? __save_stack_trace+0x5e/0x100
      [  699.862691]  ? unlink_anon_vmas+0xba/0x2c0
      [  699.863525]  save_stack_trace+0x1f/0x30
      [  699.864312]  save_stack+0x46/0xd0
      [  699.864993]  ? __alloc_pages_slowpath+0x1420/0x1420
      [  699.865990]  ? flush_tlb_mm_range+0x15e/0x220
      [  699.866889]  ? kasan_check_write+0x14/0x20
      [  699.867724]  ? __dec_node_state+0x92/0xb0
      [  699.868543]  ? lock_page_memcg+0x85/0xf0
      [  699.869350]  ? unlock_page_memcg+0x16/0x80
      [  699.870185]  ? page_remove_rmap+0x198/0x520
      [  699.871048]  ? mark_page_accessed+0x133/0x200
      [  699.871930]  ? _cond_resched+0x1a/0x50
      [  699.872700]  ? unmap_page_range+0xcd4/0xe50
      [  699.873551]  ? rb_next+0x58/0x80
      [  699.874217]  ? rb_next+0x58/0x80
      [  699.874895]  __kasan_slab_free+0x13c/0x1a0
      [  699.875734]  ? unlink_anon_vmas+0xba/0x2c0
      [  699.876563]  kasan_slab_free+0xe/0x10
      [  699.877315]  kmem_cache_free+0x89/0x1e0
      [  699.878095]  unlink_anon_vmas+0xba/0x2c0
      [  699.878913]  free_pgtables+0x101/0x1b0
      [  699.879677]  exit_mmap+0x146/0x2a0
      [  699.880378]  ? __ia32_sys_munmap+0x50/0x50
      [  699.881214]  ? kasan_check_read+0x11/0x20
      [  699.882052]  ? mm_update_next_owner+0x322/0x380
      [  699.882985]  mmput+0x8b/0x1d0
      [  699.883602]  do_exit+0x43a/0x1390
      [  699.884288]  ? mm_update_next_owner+0x380/0x380
      [  699.885212]  ? f2fs_sync_file+0x9a/0xb0
      [  699.885995]  ? f2fs_do_sync_file+0xd90/0xd90
      [  699.886877]  ? vfs_fsync_range+0x68/0x100
      [  699.887694]  ? __fget_light+0xc9/0xe0
      [  699.888442]  ? do_fsync+0x3d/0x70
      [  699.889118]  ? __x64_sys_fdatasync+0x24/0x30
      [  699.889996]  rewind_stack_do_exit+0x17/0x20
      [  699.890860] RIP: 0033:0x7f9bf930d800
      [  699.891585] Code: Bad RIP value.
      [  699.892268] RSP: 002b:00007ffee3606c68 EFLAGS: 00000246 ORIG_RAX: 000000000000004b
      [  699.893781] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f9bf930d800
      [  699.895220] RDX: 0000000000008000 RSI: 00000000006010a0 RDI: 0000000000000003
      [  699.896643] RBP: 00007ffee3606ca0 R08: 0000000001503010 R09: 0000000000000000
      [  699.898069] R10: 00000000000002e8 R11: 0000000000000246 R12: 0000000000400610
      [  699.899505] R13: 00007ffee3606da0 R14: 0000000000000000 R15: 0000000000000000
      
      [  699.901241] The buggy address belongs to the page:
      [  699.902215] page:ffffea0007d0ebc0 count:0 mapcount:0 mapping:0000000000000000 index:0x0
      [  699.903811] flags: 0x2ffff0000000000()
      [  699.904585] raw: 02ffff0000000000 0000000000000000 ffffffff07d00101 0000000000000000
      [  699.906125] raw: 0000000000000000 0000000000240000 00000000ffffffff 0000000000000000
      [  699.907673] page dumped because: kasan: bad access detected
      
      [  699.909108] Memory state around the buggy address:
      [  699.910077]  ffff8801f43af800: 00 f1 f1 f1 f1 00 f4 f4 f4 f3 f3 f3 f3 00 00 00
      [  699.911528]  ffff8801f43af880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      [  699.912953] >ffff8801f43af900: 00 00 00 00 00 00 00 00 f1 01 f4 f4 f4 f2 f2 f2
      [  699.914392]                                                              ^
      [  699.915758]  ffff8801f43af980: f2 00 f4 f4 00 00 00 00 f2 00 00 00 00 00 00 00
      [  699.917193]  ffff8801f43afa00: 00 00 00 00 00 00 00 00 00 f3 f3 f3 00 00 00 00
      [  699.918634] ==================================================================
      
      - Location
      https://elixir.bootlin.com/linux/v4.18-rc1/source/fs/f2fs/segment.h#L644
      
      Reported-by Wen Xu <wen.xu@gatech.edu>
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      c9b60788
  2. 27 7月, 2018 3 次提交
  3. 13 6月, 2018 1 次提交
    • K
      treewide: Use array_size in f2fs_kvzalloc() · 9d2a789c
      Kees Cook 提交于
      The f2fs_kvzalloc() function has no 2-factor argument form, so
      multiplication factors need to be wrapped in array_size(). This patch
      replaces cases of:
      
              f2fs_kvzalloc(handle, a * b, gfp)
      
      with:
              f2fs_kvzalloc(handle, array_size(a, b), gfp)
      
      as well as handling cases of:
      
              f2fs_kvzalloc(handle, a * b * c, gfp)
      
      with:
      
              f2fs_kvzalloc(handle, array3_size(a, b, c), gfp)
      
      This does, however, attempt to ignore constant size factors like:
      
              f2fs_kvzalloc(handle, 4 * 1024, gfp)
      
      though any constants defined via macros get caught up in the conversion.
      
      Any factors with a sizeof() of "unsigned char", "char", and "u8" were
      dropped, since they're redundant.
      
      The Coccinelle script used for this was:
      
      // Fix redundant parens around sizeof().
      @@
      expression HANDLE;
      type TYPE;
      expression THING, E;
      @@
      
      (
        f2fs_kvzalloc(HANDLE,
      -	(sizeof(TYPE)) * E
      +	sizeof(TYPE) * E
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	(sizeof(THING)) * E
      +	sizeof(THING) * E
        , ...)
      )
      
      // Drop single-byte sizes and redundant parens.
      @@
      expression HANDLE;
      expression COUNT;
      typedef u8;
      typedef __u8;
      @@
      
      (
        f2fs_kvzalloc(HANDLE,
      -	sizeof(u8) * (COUNT)
      +	COUNT
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(__u8) * (COUNT)
      +	COUNT
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(char) * (COUNT)
      +	COUNT
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(unsigned char) * (COUNT)
      +	COUNT
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(u8) * COUNT
      +	COUNT
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(__u8) * COUNT
      +	COUNT
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(char) * COUNT
      +	COUNT
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(unsigned char) * COUNT
      +	COUNT
        , ...)
      )
      
      // 2-factor product with sizeof(type/expression) and identifier or constant.
      @@
      expression HANDLE;
      type TYPE;
      expression THING;
      identifier COUNT_ID;
      constant COUNT_CONST;
      @@
      
      (
        f2fs_kvzalloc(HANDLE,
      -	sizeof(TYPE) * (COUNT_ID)
      +	array_size(COUNT_ID, sizeof(TYPE))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(TYPE) * COUNT_ID
      +	array_size(COUNT_ID, sizeof(TYPE))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(TYPE) * (COUNT_CONST)
      +	array_size(COUNT_CONST, sizeof(TYPE))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(TYPE) * COUNT_CONST
      +	array_size(COUNT_CONST, sizeof(TYPE))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(THING) * (COUNT_ID)
      +	array_size(COUNT_ID, sizeof(THING))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(THING) * COUNT_ID
      +	array_size(COUNT_ID, sizeof(THING))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(THING) * (COUNT_CONST)
      +	array_size(COUNT_CONST, sizeof(THING))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(THING) * COUNT_CONST
      +	array_size(COUNT_CONST, sizeof(THING))
        , ...)
      )
      
      // 2-factor product, only identifiers.
      @@
      expression HANDLE;
      identifier SIZE, COUNT;
      @@
      
        f2fs_kvzalloc(HANDLE,
      -	SIZE * COUNT
      +	array_size(COUNT, SIZE)
        , ...)
      
      // 3-factor product with 1 sizeof(type) or sizeof(expression), with
      // redundant parens removed.
      @@
      expression HANDLE;
      expression THING;
      identifier STRIDE, COUNT;
      type TYPE;
      @@
      
      (
        f2fs_kvzalloc(HANDLE,
      -	sizeof(TYPE) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(TYPE) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(TYPE) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(TYPE) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(THING) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(THING) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(THING) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(THING) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      )
      
      // 3-factor product with 2 sizeof(variable), with redundant parens removed.
      @@
      expression HANDLE;
      expression THING1, THING2;
      identifier COUNT;
      type TYPE1, TYPE2;
      @@
      
      (
        f2fs_kvzalloc(HANDLE,
      -	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(THING1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(THING1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(TYPE1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      )
      
      // 3-factor product, only identifiers, with redundant parens removed.
      @@
      expression HANDLE;
      identifier STRIDE, SIZE, COUNT;
      @@
      
      (
        f2fs_kvzalloc(HANDLE,
      -	(COUNT) * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	COUNT * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	COUNT * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	(COUNT) * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	COUNT * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	(COUNT) * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	(COUNT) * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	COUNT * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      )
      
      // Any remaining multi-factor products, first at least 3-factor products
      // when they're not all constants...
      @@
      expression HANDLE;
      expression E1, E2, E3;
      constant C1, C2, C3;
      @@
      
      (
        f2fs_kvzalloc(HANDLE, C1 * C2 * C3, ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	E1 * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      )
      
      // And then all remaining 2 factors products when they're not all constants.
      @@
      expression HANDLE;
      expression E1, E2;
      constant C1, C2;
      @@
      
      (
        f2fs_kvzalloc(HANDLE, C1 * C2, ...)
      |
        f2fs_kvzalloc(HANDLE,
      -	E1 * E2
      +	array_size(E1, E2)
        , ...)
      )
      Signed-off-by: NKees Cook <keescook@chromium.org>
      9d2a789c
  4. 06 6月, 2018 1 次提交
    • D
      vfs: change inode times to use struct timespec64 · 95582b00
      Deepa Dinamani 提交于
      struct timespec is not y2038 safe. Transition vfs to use
      y2038 safe struct timespec64 instead.
      
      The change was made with the help of the following cocinelle
      script. This catches about 80% of the changes.
      All the header file and logic changes are included in the
      first 5 rules. The rest are trivial substitutions.
      I avoid changing any of the function signatures or any other
      filesystem specific data structures to keep the patch simple
      for review.
      
      The script can be a little shorter by combining different cases.
      But, this version was sufficient for my usecase.
      
      virtual patch
      
      @ depends on patch @
      identifier now;
      @@
      - struct timespec
      + struct timespec64
        current_time ( ... )
        {
      - struct timespec now = current_kernel_time();
      + struct timespec64 now = current_kernel_time64();
        ...
      - return timespec_trunc(
      + return timespec64_trunc(
        ... );
        }
      
      @ depends on patch @
      identifier xtime;
      @@
       struct \( iattr \| inode \| kstat \) {
       ...
      -       struct timespec xtime;
      +       struct timespec64 xtime;
       ...
       }
      
      @ depends on patch @
      identifier t;
      @@
       struct inode_operations {
       ...
      int (*update_time) (...,
      -       struct timespec t,
      +       struct timespec64 t,
      ...);
       ...
       }
      
      @ depends on patch @
      identifier t;
      identifier fn_update_time =~ "update_time$";
      @@
       fn_update_time (...,
      - struct timespec *t,
      + struct timespec64 *t,
       ...) { ... }
      
      @ depends on patch @
      identifier t;
      @@
      lease_get_mtime( ... ,
      - struct timespec *t
      + struct timespec64 *t
        ) { ... }
      
      @te depends on patch forall@
      identifier ts;
      local idexpression struct inode *inode_node;
      identifier i_xtime =~ "^i_[acm]time$";
      identifier ia_xtime =~ "^ia_[acm]time$";
      identifier fn_update_time =~ "update_time$";
      identifier fn;
      expression e, E3;
      local idexpression struct inode *node1;
      local idexpression struct inode *node2;
      local idexpression struct iattr *attr1;
      local idexpression struct iattr *attr2;
      local idexpression struct iattr attr;
      identifier i_xtime1 =~ "^i_[acm]time$";
      identifier i_xtime2 =~ "^i_[acm]time$";
      identifier ia_xtime1 =~ "^ia_[acm]time$";
      identifier ia_xtime2 =~ "^ia_[acm]time$";
      @@
      (
      (
      - struct timespec ts;
      + struct timespec64 ts;
      |
      - struct timespec ts = current_time(inode_node);
      + struct timespec64 ts = current_time(inode_node);
      )
      
      <+... when != ts
      (
      - timespec_equal(&inode_node->i_xtime, &ts)
      + timespec64_equal(&inode_node->i_xtime, &ts)
      |
      - timespec_equal(&ts, &inode_node->i_xtime)
      + timespec64_equal(&ts, &inode_node->i_xtime)
      |
      - timespec_compare(&inode_node->i_xtime, &ts)
      + timespec64_compare(&inode_node->i_xtime, &ts)
      |
      - timespec_compare(&ts, &inode_node->i_xtime)
      + timespec64_compare(&ts, &inode_node->i_xtime)
      |
      ts = current_time(e)
      |
      fn_update_time(..., &ts,...)
      |
      inode_node->i_xtime = ts
      |
      node1->i_xtime = ts
      |
      ts = inode_node->i_xtime
      |
      <+... attr1->ia_xtime ...+> = ts
      |
      ts = attr1->ia_xtime
      |
      ts.tv_sec
      |
      ts.tv_nsec
      |
      btrfs_set_stack_timespec_sec(..., ts.tv_sec)
      |
      btrfs_set_stack_timespec_nsec(..., ts.tv_nsec)
      |
      - ts = timespec64_to_timespec(
      + ts =
      ...
      -)
      |
      - ts = ktime_to_timespec(
      + ts = ktime_to_timespec64(
      ...)
      |
      - ts = E3
      + ts = timespec_to_timespec64(E3)
      |
      - ktime_get_real_ts(&ts)
      + ktime_get_real_ts64(&ts)
      |
      fn(...,
      - ts
      + timespec64_to_timespec(ts)
      ,...)
      )
      ...+>
      (
      <... when != ts
      - return ts;
      + return timespec64_to_timespec(ts);
      ...>
      )
      |
      - timespec_equal(&node1->i_xtime1, &node2->i_xtime2)
      + timespec64_equal(&node1->i_xtime2, &node2->i_xtime2)
      |
      - timespec_equal(&node1->i_xtime1, &attr2->ia_xtime2)
      + timespec64_equal(&node1->i_xtime2, &attr2->ia_xtime2)
      |
      - timespec_compare(&node1->i_xtime1, &node2->i_xtime2)
      + timespec64_compare(&node1->i_xtime1, &node2->i_xtime2)
      |
      node1->i_xtime1 =
      - timespec_trunc(attr1->ia_xtime1,
      + timespec64_trunc(attr1->ia_xtime1,
      ...)
      |
      - attr1->ia_xtime1 = timespec_trunc(attr2->ia_xtime2,
      + attr1->ia_xtime1 =  timespec64_trunc(attr2->ia_xtime2,
      ...)
      |
      - ktime_get_real_ts(&attr1->ia_xtime1)
      + ktime_get_real_ts64(&attr1->ia_xtime1)
      |
      - ktime_get_real_ts(&attr.ia_xtime1)
      + ktime_get_real_ts64(&attr.ia_xtime1)
      )
      
      @ depends on patch @
      struct inode *node;
      struct iattr *attr;
      identifier fn;
      identifier i_xtime =~ "^i_[acm]time$";
      identifier ia_xtime =~ "^ia_[acm]time$";
      expression e;
      @@
      (
      - fn(node->i_xtime);
      + fn(timespec64_to_timespec(node->i_xtime));
      |
       fn(...,
      - node->i_xtime);
      + timespec64_to_timespec(node->i_xtime));
      |
      - e = fn(attr->ia_xtime);
      + e = fn(timespec64_to_timespec(attr->ia_xtime));
      )
      
      @ depends on patch forall @
      struct inode *node;
      struct iattr *attr;
      identifier i_xtime =~ "^i_[acm]time$";
      identifier ia_xtime =~ "^ia_[acm]time$";
      identifier fn;
      @@
      {
      + struct timespec ts;
      <+...
      (
      + ts = timespec64_to_timespec(node->i_xtime);
      fn (...,
      - &node->i_xtime,
      + &ts,
      ...);
      |
      + ts = timespec64_to_timespec(attr->ia_xtime);
      fn (...,
      - &attr->ia_xtime,
      + &ts,
      ...);
      )
      ...+>
      }
      
      @ depends on patch forall @
      struct inode *node;
      struct iattr *attr;
      struct kstat *stat;
      identifier ia_xtime =~ "^ia_[acm]time$";
      identifier i_xtime =~ "^i_[acm]time$";
      identifier xtime =~ "^[acm]time$";
      identifier fn, ret;
      @@
      {
      + struct timespec ts;
      <+...
      (
      + ts = timespec64_to_timespec(node->i_xtime);
      ret = fn (...,
      - &node->i_xtime,
      + &ts,
      ...);
      |
      + ts = timespec64_to_timespec(node->i_xtime);
      ret = fn (...,
      - &node->i_xtime);
      + &ts);
      |
      + ts = timespec64_to_timespec(attr->ia_xtime);
      ret = fn (...,
      - &attr->ia_xtime,
      + &ts,
      ...);
      |
      + ts = timespec64_to_timespec(attr->ia_xtime);
      ret = fn (...,
      - &attr->ia_xtime);
      + &ts);
      |
      + ts = timespec64_to_timespec(stat->xtime);
      ret = fn (...,
      - &stat->xtime);
      + &ts);
      )
      ...+>
      }
      
      @ depends on patch @
      struct inode *node;
      struct inode *node2;
      identifier i_xtime1 =~ "^i_[acm]time$";
      identifier i_xtime2 =~ "^i_[acm]time$";
      identifier i_xtime3 =~ "^i_[acm]time$";
      struct iattr *attrp;
      struct iattr *attrp2;
      struct iattr attr ;
      identifier ia_xtime1 =~ "^ia_[acm]time$";
      identifier ia_xtime2 =~ "^ia_[acm]time$";
      struct kstat *stat;
      struct kstat stat1;
      struct timespec64 ts;
      identifier xtime =~ "^[acmb]time$";
      expression e;
      @@
      (
      ( node->i_xtime2 \| attrp->ia_xtime2 \| attr.ia_xtime2 \) = node->i_xtime1  ;
      |
       node->i_xtime2 = \( node2->i_xtime1 \| timespec64_trunc(...) \);
      |
       node->i_xtime2 = node->i_xtime1 = node->i_xtime3 = \(ts \| current_time(...) \);
      |
       node->i_xtime1 = node->i_xtime3 = \(ts \| current_time(...) \);
      |
       stat->xtime = node2->i_xtime1;
      |
       stat1.xtime = node2->i_xtime1;
      |
      ( node->i_xtime2 \| attrp->ia_xtime2 \) = attrp->ia_xtime1  ;
      |
      ( attrp->ia_xtime1 \| attr.ia_xtime1 \) = attrp2->ia_xtime2;
      |
      - e = node->i_xtime1;
      + e = timespec64_to_timespec( node->i_xtime1 );
      |
      - e = attrp->ia_xtime1;
      + e = timespec64_to_timespec( attrp->ia_xtime1 );
      |
      node->i_xtime1 = current_time(...);
      |
       node->i_xtime2 = node->i_xtime1 = node->i_xtime3 =
      - e;
      + timespec_to_timespec64(e);
      |
       node->i_xtime1 = node->i_xtime3 =
      - e;
      + timespec_to_timespec64(e);
      |
      - node->i_xtime1 = e;
      + node->i_xtime1 = timespec_to_timespec64(e);
      )
      Signed-off-by: NDeepa Dinamani <deepa.kernel@gmail.com>
      Cc: <anton@tuxera.com>
      Cc: <balbi@kernel.org>
      Cc: <bfields@fieldses.org>
      Cc: <darrick.wong@oracle.com>
      Cc: <dhowells@redhat.com>
      Cc: <dsterba@suse.com>
      Cc: <dwmw2@infradead.org>
      Cc: <hch@lst.de>
      Cc: <hirofumi@mail.parknet.co.jp>
      Cc: <hubcap@omnibond.com>
      Cc: <jack@suse.com>
      Cc: <jaegeuk@kernel.org>
      Cc: <jaharkes@cs.cmu.edu>
      Cc: <jslaby@suse.com>
      Cc: <keescook@chromium.org>
      Cc: <mark@fasheh.com>
      Cc: <miklos@szeredi.hu>
      Cc: <nico@linaro.org>
      Cc: <reiserfs-devel@vger.kernel.org>
      Cc: <richard@nod.at>
      Cc: <sage@redhat.com>
      Cc: <sfrench@samba.org>
      Cc: <swhiteho@redhat.com>
      Cc: <tj@kernel.org>
      Cc: <trond.myklebust@primarydata.com>
      Cc: <tytso@mit.edu>
      Cc: <viro@zeniv.linux.org.uk>
      95582b00
  5. 05 6月, 2018 2 次提交
    • C
      f2fs: fix to clear FI_VOLATILE_FILE correctly · dfa74280
      Chao Yu 提交于
      Thread A			Thread B
      - f2fs_release_file
       - clear_inode_flag(FI_VOLATILE_FILE)
      				- wb_writeback
      				 - writeback_sb_inodes
      				  - __writeback_single_inode
      				   - do_writepages
      				    - f2fs_write_data_pages
      				     - __write_data_page
      				     all volatile file's pages
      				     are writebacked to storage
       - set_inode_flag(FI_DROP_CACHE)
       - filemap_fdatawrite
      
      There is a hole that mm can flush all dirty pages of volatile file as
      inode is not tagged with both FI_VOLATILE_FILE and FI_DROP_CACHE flags,
      we should never writeback the page #0 and also it's unneeded to writeback
      other pages.
      
      This patch adjusts to relocate clear_inode_flag(FI_VOLATILE_FILE), so that
      FI_VOLATILE_FILE flag can be remained before all dirty pages were dropped
      to avoid issue.
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      dfa74280
    • C
      f2fs: let sync node IO interrupt async one · c29fd0c0
      Chao Yu 提交于
      Although mixed sync/async IOs can have continuous LBA, as they have
      different IO priority, block IO scheduler will add them into different
      queues and commit them separately, result in splited IOs which causes
      wrose performance.
      
      This patch gives high priority to synchronous IO of nodes, means that
      once synchronous flow starts, it can interrupt asynchronous writeback
      flow of system flusher, so more big IOs can be expected.
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      c29fd0c0
  6. 01 6月, 2018 21 次提交
  7. 30 5月, 2018 1 次提交
  8. 03 5月, 2018 1 次提交
    • E
      f2fs: refactor read path to allow multiple postprocessing steps · 6dbb1796
      Eric Biggers 提交于
      Currently f2fs's ->readpage() and ->readpages() assume that either the
      data undergoes no postprocessing, or decryption only.  But with
      fs-verity, there will be an additional authenticity verification step,
      and it may be needed either by itself, or combined with decryption.
      
      To support this, store a 'struct bio_post_read_ctx' in ->bi_private
      which contains a work struct, a bitmask of postprocessing steps that are
      enabled, and an indicator of the current step.  The bio completion
      routine, if there was no I/O error, enqueues the first postprocessing
      step.  When that completes, it continues to the next step.  Pages that
      fail any postprocessing step have PageError set.  Once all steps have
      completed, pages without PageError set are set Uptodate, and all pages
      are unlocked.
      
      Also replace f2fs_encrypted_file() with a new function
      f2fs_post_read_required() in places like direct I/O and garbage
      collection that really should be testing whether the file needs special
      I/O processing, not whether it is encrypted specifically.
      
      This may also be useful for other future f2fs features such as
      compression.
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Reviewed-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      6dbb1796
  9. 03 4月, 2018 1 次提交
  10. 28 3月, 2018 1 次提交
  11. 17 3月, 2018 4 次提交
  12. 13 3月, 2018 2 次提交
    • C
      f2fs: fix to avoid race in between atomic write and background GC · 1dc0f899
      Chao Yu 提交于
      Sqlite user			Background GC
      				- move_data_block
      				  : move page #1
      				 - f2fs_is_atomic_file
      - f2fs_ioc_start_atomic_write
      - f2fs_ioc_commit_atomic_write
       - commit_inmem_pages
         : commit page #1 & set node #2 dirty
      				 - f2fs_submit_page_write
      				  - f2fs_update_data_blkaddr
      				   - set_page_dirty
      				     : set node #2 dirty
       - f2fs_do_sync_file
        - fsync_node_pages
         : commit node #1 & node #2, then sudden power-cut
      
      In a race case, we may check FI_ATOMIC_FILE flag before starting atomic
      write flow, then we will commit meta data before data with reversed
      order, after a sudden pow-cut, database transaction will be inconsistent.
      
      So we'd better to exclude gc/atomic_write to each other by using lock
      instead of flag checking.
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      1dc0f899
    • C
      f2fs: expose extension_list sysfs entry · 846ae671
      Chao Yu 提交于
      This patch adds a sysfs entry 'extension_list' to support
      query/add/del item in extension list.
      
      Query:
      cat /sys/fs/f2fs/<device>/extension_list
      
      Add:
      echo 'extension' > /sys/fs/f2fs/<device>/extension_list
      
      Del:
      echo '!extension' > /sys/fs/f2fs/<device>/extension_list
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      846ae671