1. 21 5月, 2016 1 次提交
  2. 11 5月, 2016 1 次提交
  3. 02 5月, 2016 3 次提交
  4. 13 4月, 2016 2 次提交
  5. 11 4月, 2016 2 次提交
  6. 05 4月, 2016 1 次提交
    • K
      mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros · 09cbfeaf
      Kirill A. Shutemov 提交于
      PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} macros were introduced *long* time
      ago with promise that one day it will be possible to implement page
      cache with bigger chunks than PAGE_SIZE.
      
      This promise never materialized.  And unlikely will.
      
      We have many places where PAGE_CACHE_SIZE assumed to be equal to
      PAGE_SIZE.  And it's constant source of confusion on whether
      PAGE_CACHE_* or PAGE_* constant should be used in a particular case,
      especially on the border between fs and mm.
      
      Global switching to PAGE_CACHE_SIZE != PAGE_SIZE would cause to much
      breakage to be doable.
      
      Let's stop pretending that pages in page cache are special.  They are
      not.
      
      The changes are pretty straight-forward:
      
       - <foo> << (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
      
       - <foo> >> (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
      
       - PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} -> PAGE_{SIZE,SHIFT,MASK,ALIGN};
      
       - page_cache_get() -> get_page();
      
       - page_cache_release() -> put_page();
      
      This patch contains automated changes generated with coccinelle using
      script below.  For some reason, coccinelle doesn't patch header files.
      I've called spatch for them manually.
      
      The only adjustment after coccinelle is revert of changes to
      PAGE_CAHCE_ALIGN definition: we are going to drop it later.
      
      There are few places in the code where coccinelle didn't reach.  I'll
      fix them manually in a separate patch.  Comments and documentation also
      will be addressed with the separate patch.
      
      virtual patch
      
      @@
      expression E;
      @@
      - E << (PAGE_CACHE_SHIFT - PAGE_SHIFT)
      + E
      
      @@
      expression E;
      @@
      - E >> (PAGE_CACHE_SHIFT - PAGE_SHIFT)
      + E
      
      @@
      @@
      - PAGE_CACHE_SHIFT
      + PAGE_SHIFT
      
      @@
      @@
      - PAGE_CACHE_SIZE
      + PAGE_SIZE
      
      @@
      @@
      - PAGE_CACHE_MASK
      + PAGE_MASK
      
      @@
      expression E;
      @@
      - PAGE_CACHE_ALIGN(E)
      + PAGE_ALIGN(E)
      
      @@
      expression E;
      @@
      - page_cache_get(E)
      + get_page(E)
      
      @@
      expression E;
      @@
      - page_cache_release(E)
      + put_page(E)
      Signed-off-by: NKirill A. Shutemov <kirill.shutemov@linux.intel.com>
      Acked-by: NMichal Hocko <mhocko@suse.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      09cbfeaf
  7. 31 3月, 2016 3 次提交
    • A
      posix_acl: Inode acl caching fixes · b8a7a3a6
      Andreas Gruenbacher 提交于
      When get_acl() is called for an inode whose ACL is not cached yet, the
      get_acl inode operation is called to fetch the ACL from the filesystem.
      The inode operation is responsible for updating the cached acl with
      set_cached_acl().  This is done without locking at the VFS level, so
      another task can call set_cached_acl() or forget_cached_acl() before the
      get_acl inode operation gets to calling set_cached_acl(), and then
      get_acl's call to set_cached_acl() results in caching an outdate ACL.
      
      Prevent this from happening by setting the cached ACL pointer to a
      task-specific sentinel value before calling the get_acl inode operation.
      Move the responsibility for updating the cached ACL from the get_acl
      inode operations to get_acl().  There, only set the cached ACL if the
      sentinel value hasn't changed.
      
      The sentinel values are chosen to have odd values.  Likewise, the value
      of ACL_NOT_CACHED is odd.  In contrast, ACL object pointers always have
      an even value (ACLs are aligned in memory).  This allows to distinguish
      uncached ACLs values from ACL objects.
      
      In addition, switch from guarding inode->i_acl and inode->i_default_acl
      upates by the inode->i_lock spinlock to using xchg() and cmpxchg().
      
      Filesystems that do not want ACLs returned from their get_acl inode
      operations to be cached must call forget_cached_acl() to prevent the VFS
      from doing so.
      
      (Patch written by Al Viro and Andreas Gruenbacher.)
      Signed-off-by: NAndreas Gruenbacher <agruenba@redhat.com>
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      b8a7a3a6
    • S
      f2fs: retrieve IO write stat from the right place · b2dde6fc
      Shuoran Liu 提交于
      In the following patch,
      
          f2fs: split journal cache from curseg cache
      
      journal cache is split from curseg cache. So IO write statistics should be
      retrived from journal cache but not curseg->sum_blk. Otherwise, it will
      get 0, and the stat is lost.
      Signed-off-by: NShuoran Liu <liushuoran@huawei.com>
      Reviewed-by: NChao Yu <chao@kernel.org>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      b2dde6fc
    • J
      f2fs crypto: fix corrupted symlink in encrypted case · c90e09f7
      Jaegeuk Kim 提交于
      In the encrypted symlink case, we should check its corrupted symname after
      decrypting it.
      Otherwise, we can report -ENOENT incorrectly, if encrypted symname starts with
      '\0'.
      
      Cc: stable 4.5+ <stable@vger.kernel.org>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      c90e09f7
  8. 29 3月, 2016 1 次提交
  9. 18 3月, 2016 9 次提交
  10. 03 3月, 2016 2 次提交
    • Y
      f2fs: mutex can't be used by down_write_nest_lock() · 59692b7c
      Yang Shi 提交于
      f2fs_lock_all() calls down_write_nest_lock() to acquire a rw_sem and check
      a mutex, but down_write_nest_lock() is designed for two rw_sem accoring to the
      comment in include/linux/rwsem.h. And, other than f2fs, it is just called in
      mm/mmap.c with two rwsem.
      
      So, it looks it is used wrongly by f2fs. And, it causes the below compile
      warning on -rt kernel too.
      
      In file included from fs/f2fs/xattr.c:25:0:
      fs/f2fs/f2fs.h: In function 'f2fs_lock_all':
      fs/f2fs/f2fs.h:962:34: warning: passing argument 2 of 'down_write_nest_lock' from incompatible pointer type [-Wincompatible-pointer-types]
        f2fs_down_write(&sbi->cp_rwsem, &sbi->cp_mutex);
                                        ^
      fs/f2fs/f2fs.h:27:55: note: in definition of macro 'f2fs_down_write'
       #define f2fs_down_write(x, y) down_write_nest_lock(x, y)
                                                             ^
      In file included from include/linux/rwsem.h:22:0,
                       from fs/f2fs/xattr.c:21:
      include/linux/rwsem_rt.h:138:20: note: expected 'struct rw_semaphore *' but argument is of type 'struct mutex *'
       static inline void down_write_nest_lock(struct rw_semaphore *sem,
      Signed-off-by: NYang Shi <yang.shi@linaro.org>
      Reviewed-by: NChao Yu <chao2.yu@samsung.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      59692b7c
    • L
      f2fs: recovery missing dot dentries in root directory · 8c2b1435
      Liu Xue 提交于
      If f2fs was corrupted with missing dot dentries in root dirctory,
      it needs to recover them after fsck.f2fs set F2FS_INLINE_DOTS flag
      in directory inode when fsck.f2fs detects missing dot dentries.
      Signed-off-by: NXue Liu <liuxueliu.liu@huawei.com>
      Signed-off-by: NYong Sheng <shengyong1@huawei.com>
      Reviewed-by: NChao Yu <chao2.yu@samsung.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      8c2b1435
  11. 27 2月, 2016 4 次提交
    • C
      f2fs: fix to avoid deadlock when merging inline data · 19c7377b
      Chao Yu 提交于
      When testing with fsstress, kworker and user threads were both blocked:
      
      INFO: task kworker/u16:1:16580 blocked for more than 120 seconds.
      "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
      kworker/u16:1   D ffff8803f2595390     0 16580      2 0x00000000
      Workqueue: writeback bdi_writeback_workfn (flush-251:0)
       ffff8802730e5760 0000000000000046 ffff880274729fc0 0000000000012440
       ffff8802730e5fd8 ffff8802730e4010 0000000000012440 0000000000012440
       ffff8802730e5fd8 0000000000012440 ffff880274729fc0 ffff88026eb50000
      Call Trace:
       [<ffffffff816fe9d9>] schedule+0x29/0x70
       [<ffffffff816ff895>] rwsem_down_read_failed+0xa5/0xf9
       [<ffffffff81378584>] call_rwsem_down_read_failed+0x14/0x30
       [<ffffffffa0694feb>] f2fs_write_data_page+0x31b/0x420 [f2fs]
       [<ffffffffa0690f1a>] __f2fs_writepage+0x1a/0x50 [f2fs]
       [<ffffffffa06922a0>] f2fs_write_data_pages+0xe0/0x290 [f2fs]
       [<ffffffff811473b3>] do_writepages+0x23/0x40
       [<ffffffff811cc3ee>] __writeback_single_inode+0x4e/0x250
       [<ffffffff811cd4f1>] writeback_sb_inodes+0x2c1/0x470
       [<ffffffff811cd73e>] __writeback_inodes_wb+0x9e/0xd0
       [<ffffffff811cda0b>] wb_writeback+0x1fb/0x2d0
       [<ffffffff811cdb7c>] wb_do_writeback+0x9c/0x220
       [<ffffffff811ce232>] bdi_writeback_workfn+0x72/0x1c0
       [<ffffffff8106b74e>] process_one_work+0x1de/0x5b0
       [<ffffffff8106e78f>] worker_thread+0x11f/0x3e0
       [<ffffffff810750ce>] kthread+0xde/0xf0
       [<ffffffff817093f8>] ret_from_fork+0x58/0x90
      
      fsstress thread stack:
       [<ffffffff81139f0e>] sleep_on_page+0xe/0x20
       [<ffffffff81139ef7>] __lock_page+0x67/0x70
       [<ffffffff8113b100>] find_lock_page+0x50/0x80
       [<ffffffff8113b24f>] find_or_create_page+0x3f/0xb0
       [<ffffffffa06983a9>] sync_node_pages+0x259/0x810 [f2fs]
       [<ffffffffa068d874>] write_checkpoint+0x1a4/0xce0 [f2fs]
       [<ffffffffa0686b0c>] f2fs_sync_fs+0x7c/0xd0 [f2fs]
       [<ffffffffa067c813>] f2fs_sync_file+0x143/0x5f0 [f2fs]
       [<ffffffff811d301b>] vfs_fsync_range+0x2b/0x40
       [<ffffffff811d304c>] vfs_fsync+0x1c/0x20
       [<ffffffff811d3291>] do_fsync+0x41/0x70
       [<ffffffff811d32d3>] SyS_fdatasync+0x13/0x20
       [<ffffffff817094a2>] system_call_fastpath+0x16/0x1b
       [<ffffffffffffffff>] 0xffffffffffffffff
      
      The reason of this issue is:
      CPU0:					CPU1:
       - f2fs_write_data_pages
      					 - f2fs_sync_fs
      					  - write_checkpoint
      					   - block_operations
      					    - f2fs_lock_all
      					     - down_write(sbi->cp_rwsem)
        - lock_page(page)
        - f2fs_write_data_page
      					    - sync_node_pages
      					     - flush_inline_data
      					      - pagecache_get_page(page, GFP_LOCK)
         - f2fs_lock_op
          - down_read(sbi->cp_rwsem)
      
      This patch alters to use trylock_page in flush_inline_data to fix this ABBA
      deadlock issue.
      Signed-off-by: NChao Yu <chao2.yu@samsung.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      19c7377b
    • C
      f2fs: introduce f2fs_flush_merged_bios for cleanup · 406657dd
      Chao Yu 提交于
      Add a new helper f2fs_flush_merged_bios to clean up redundant codes.
      Signed-off-by: NChao Yu <chao2.yu@samsung.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      406657dd
    • C
      f2fs: introduce f2fs_update_data_blkaddr for cleanup · f28b3434
      Chao Yu 提交于
      Add a new help f2fs_update_data_blkaddr to clean up redundant codes.
      Signed-off-by: NChao Yu <chao2.yu@samsung.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      f28b3434
    • C
      f2fs crypto: fix incorrect positioning for GCing encrypted data page · 4356e48e
      Chao Yu 提交于
      For now, flow of GCing an encrypted data page:
      1) try to grab meta page in meta inode's mapping with index of old block
      address of that data page
      2) load data of ciphertext into meta page
      3) allocate new block address
      4) write the meta page into new block address
      5) update block address pointer in direct node page.
      
      Other reader/writer will use f2fs_wait_on_encrypted_page_writeback to
      check and wait on GCed encrypted data cached in meta page writebacked
      in order to avoid inconsistence among data page cache, meta page cache
      and data on-disk when updating.
      
      However, we will use new block address updated in step 5) as an index to
      lookup meta page in inner bio buffer. That would be wrong, and we will
      never find the GCing meta page, since we use the old block address as
      index of that page in step 1).
      
      This patch fixes the issue by adjust the order of step 1) and step 3),
      and in step 1) grab page with index generated in step 3).
      Signed-off-by: NChao Yu <chao2.yu@samsung.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      4356e48e
  12. 26 2月, 2016 1 次提交
    • C
      f2fs: fix incorrect upper bound when iterating inode mapping tree · 80dd9c0e
      Chao Yu 提交于
      1. Inode mapping tree can index page in range of [0, ULONG_MAX], however,
      in some places, f2fs only search or iterate page in ragne of [0, LONG_MAX],
      result in miss hitting in page cache.
      
      2. filemap_fdatawait_range accepts range parameters in unit of bytes, so
      the max range it covers should be [0, LLONG_MAX], if we use [0, LONG_MAX]
      as range for waiting on writeback, big number of pages will not be covered.
      
      This patch corrects above two issues.
      Signed-off-by: NChao Yu <chao2.yu@samsung.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      80dd9c0e
  13. 24 2月, 2016 1 次提交
  14. 23 2月, 2016 9 次提交
    • C
      f2fs: trace old block address for CoWed page · 7a9d7548
      Chao Yu 提交于
      This patch enables to trace old block address of CoWed page for better
      debugging.
      
      f2fs_submit_page_mbio: dev = (1,0), ino = 1, page_index = 0x1d4f0, oldaddr = 0xfe8ab, newaddr = 0xfee90 rw = WRITE_SYNC, type = NODE
      f2fs_submit_page_mbio: dev = (1,0), ino = 1, page_index = 0x1d4f8, oldaddr = 0xfe8b0, newaddr = 0xfee91 rw = WRITE_SYNC, type = NODE
      f2fs_submit_page_mbio: dev = (1,0), ino = 1, page_index = 0x1d4fa, oldaddr = 0xfe8ae, newaddr = 0xfee92 rw = WRITE_SYNC, type = NODE
      
      f2fs_submit_page_mbio: dev = (1,0), ino = 134824, page_index = 0x96, oldaddr = 0xf049b, newaddr = 0x2bbe rw = WRITE, type = DATA
      f2fs_submit_page_mbio: dev = (1,0), ino = 134824, page_index = 0x97, oldaddr = 0xf049c, newaddr = 0x2bbf rw = WRITE, type = DATA
      f2fs_submit_page_mbio: dev = (1,0), ino = 134824, page_index = 0x98, oldaddr = 0xf049d, newaddr = 0x2bc0 rw = WRITE, type = DATA
      
      f2fs_submit_page_mbio: dev = (1,0), ino = 135260, page_index = 0x47, oldaddr = 0xffffffff, newaddr = 0xf2631 rw = WRITE, type = DATA
      f2fs_submit_page_mbio: dev = (1,0), ino = 135260, page_index = 0x48, oldaddr = 0xffffffff, newaddr = 0xf2632 rw = WRITE, type = DATA
      f2fs_submit_page_mbio: dev = (1,0), ino = 135260, page_index = 0x49, oldaddr = 0xffffffff, newaddr = 0xf2633 rw = WRITE, type = DATA
      Signed-off-by: NChao Yu <chao2.yu@samsung.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      7a9d7548
    • C
      f2fs: try to flush inode after merging inline data · 9a4cbc9e
      Chao Yu 提交于
      When flushing node pages, if current node page is an inline inode page, we
      will try to merge inline data from data page into inline inode page, then
      skip flushing current node page, it will decrease the number of nodes to
      be flushed in batch in this round, which may lead to worse performance.
      
      This patch gives a chance to flush just merged inline inode pages for
      performance.
      Signed-off-by: NChao Yu <chao2.yu@samsung.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      9a4cbc9e
    • C
      f2fs: show more info about superblock recovery · 41214b3c
      Chao Yu 提交于
      This patch changes to show more info in message log about the recovery
      of the corrupted superblock during ->mount, e.g. the index of corrupted
      superblock and the result of recovery.
      Signed-off-by: NChao Yu <chao2.yu@samsung.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      41214b3c
    • C
      f2fs: fix the wrong stat count of calling gc · 17d899df
      Chao Yu 提交于
      With a partition which was formated as multi segments in one section,
      we stated incorrectly for count of gc operation.
      
      e.g., for a partition with segs_per_sec = 4
      
      cat /sys/kernel/debug/f2fs/status
      
      GC calls: 208 (BG: 7)
        - data segments : 104 (52)
        - node segments : 104 (24)
      
      GC called count should be (104 (data segs) + 104 (node segs)) / 4 = 52,
      rather than 208. Fix it.
      Signed-off-by: NChao Yu <chao2.yu@samsung.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      17d899df
    • J
      f2fs: remain last victim segment number ascending order · 4ce53776
      Jaegeuk Kim 提交于
      This patch avoids to remain inefficient victim segment number selected by
      a victim.
      
      For example, if all the dirty segments has same valid blocks, we can get
      the victim segments descending order due to keeping wrong last segment number.
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      4ce53776
    • S
      f2fs: reuse read_inline_data for f2fs_convert_inline_page · 8060656a
      Shawn Lin 提交于
      f2fs_convert_inline_page introduce what read_inline_data
      already does for copying out the inline data from inode_page.
      We can use read_inline_data instead to simplify the code.
      Signed-off-by: NShawn Lin <shawn.lin@rock-chips.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      8060656a
    • C
      f2fs: fix to delete old dirent in converted inline directory in ->rename · 993a0499
      Chao Yu 提交于
      When doing test with fstests/generic/068 in inline_dentry enabled f2fs,
      following oops dmesg will be reported:
      
       ------------[ cut here ]------------
       WARNING: CPU: 5 PID: 11841 at fs/inode.c:273 drop_nlink+0x49/0x50()
       Modules linked in: f2fs(O) ip6table_filter ip6_tables ebtable_nat ebtables nf_conntrack_ipv4 nf_defrag_ipv4 xt_state
       CPU: 5 PID: 11841 Comm: fsstress Tainted: G           O    4.5.0-rc1 #45
       Hardware name: Hewlett-Packard HP Z220 CMT Workstation/1790, BIOS K51 v01.61 05/16/2013
        0000000000000111 ffff88009cdf7ae8 ffffffff813e5944 0000000000002e41
        0000000000000000 0000000000000111 0000000000000000 ffff88009cdf7b28
        ffffffff8106a587 ffff88009cdf7b58 ffff8804078fe180 ffff880374a64e00
       Call Trace:
        [<ffffffff813e5944>] dump_stack+0x48/0x64
        [<ffffffff8106a587>] warn_slowpath_common+0x97/0xe0
        [<ffffffff8106a5ea>] warn_slowpath_null+0x1a/0x20
        [<ffffffff81231039>] drop_nlink+0x49/0x50
        [<ffffffffa07b95b4>] f2fs_rename2+0xe04/0x10c0 [f2fs]
        [<ffffffff81231ff1>] ? lock_two_nondirectories+0x81/0x90
        [<ffffffff813f454d>] ? lockref_get+0x1d/0x30
        [<ffffffff81220f70>] vfs_rename+0x2e0/0x640
        [<ffffffff8121f9db>] ? lookup_dcache+0x3b/0xd0
        [<ffffffff810b8e41>] ? update_fast_ctr+0x21/0x40
        [<ffffffff8134ff12>] ? security_path_rename+0xa2/0xd0
        [<ffffffff81224af6>] SYSC_renameat2+0x4b6/0x540
        [<ffffffff810ba8ed>] ? trace_hardirqs_off+0xd/0x10
        [<ffffffff810022ba>] ? exit_to_usermode_loop+0x7a/0xd0
        [<ffffffff817e0ade>] ? int_ret_from_sys_call+0x52/0x9f
        [<ffffffff810bdc90>] ? trace_hardirqs_on_caller+0x100/0x1c0
        [<ffffffff81224b8e>] SyS_renameat2+0xe/0x10
        [<ffffffff8121f08e>] SyS_rename+0x1e/0x20
        [<ffffffff817e0957>] entry_SYSCALL_64_fastpath+0x12/0x6f
       ---[ end trace 2b31e17995404e42 ]---
      
      This is because: in the same inline directory, when we renaming one file
      from source name to target name which is not existed, once space of inline
      dentry is not enough, inline conversion will be triggered, after that all
      data in inline dentry will be moved to normal dentry page.
      
      After attaching the new entry in coverted dentry page, still we try to
      remove old entry in original inline dentry, since old entry has been
      moved, so it obviously doesn't make any effect, result in remaining old
      entry in converted dentry page.
      
      Now, we have two valid dentries pointed to the same inode which has nlink
      value of 1, deleting them both, above warning appears.
      
      This issue can be reproduced easily as below steps:
      1. mount f2fs with inline_dentry option
      2. mkdir dir
      3. touch 180 files named [001-180] in dir
      4. rename dir/180 dir/181
      5. rm dir/180 dir/181
      Signed-off-by: NChao Yu <chao2.yu@samsung.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      993a0499
    • C
      f2fs: detect error of update_dent_inode in ->rename · 9def1e92
      Chao Yu 提交于
      Should check and show correct return value of update_dent_inode in
      ->rename.
      Signed-off-by: NChao Yu <chao2.yu@samsung.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      9def1e92
    • S
      f2fs: move sanity checking of cp into get_valid_checkpoint · 984ec63c
      Shawn Lin 提交于
      >From the function name of get_valid_checkpoint, it seems to return
      the valid cp or NULL for caller to check. If no valid one is found,
      f2fs_fill_super will print the err log. But if get_valid_checkpoint
      get one valid(the return value indicate that it's valid, however actually
      it is invalid after sanity checking), then print another similar err
      log. That seems strange. Let's keep sanity checking inside the procedure
      of geting valid cp. Another improvement we gained from this move is
      that even the large volume is supported, we check the cp in advanced
      to skip the following procedure if failing the sanity checking.
      Signed-off-by: NShawn Lin <shawn.lin@rock-chips.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      984ec63c