linux_dsm_epyc7002/fs/ocfs2
Wengang Wang f5785283dd ocfs2: initialize ip_next_orphan
Though problem if found on a lower 4.1.12 kernel, I think upstream has
same issue.

In one node in the cluster, there is the following callback trace:

   # cat /proc/21473/stack
   __ocfs2_cluster_lock.isra.36+0x336/0x9e0 [ocfs2]
   ocfs2_inode_lock_full_nested+0x121/0x520 [ocfs2]
   ocfs2_evict_inode+0x152/0x820 [ocfs2]
   evict+0xae/0x1a0
   iput+0x1c6/0x230
   ocfs2_orphan_filldir+0x5d/0x100 [ocfs2]
   ocfs2_dir_foreach_blk+0x490/0x4f0 [ocfs2]
   ocfs2_dir_foreach+0x29/0x30 [ocfs2]
   ocfs2_recover_orphans+0x1b6/0x9a0 [ocfs2]
   ocfs2_complete_recovery+0x1de/0x5c0 [ocfs2]
   process_one_work+0x169/0x4a0
   worker_thread+0x5b/0x560
   kthread+0xcb/0xf0
   ret_from_fork+0x61/0x90

The above stack is not reasonable, the final iput shouldn't happen in
ocfs2_orphan_filldir() function.  Looking at the code,

  2067         /* Skip inodes which are already added to recover list, since dio may
  2068          * happen concurrently with unlink/rename */
  2069         if (OCFS2_I(iter)->ip_next_orphan) {
  2070                 iput(iter);
  2071                 return 0;
  2072         }
  2073

The logic thinks the inode is already in recover list on seeing
ip_next_orphan is non-NULL, so it skip this inode after dropping a
reference which incremented in ocfs2_iget().

While, if the inode is already in recover list, it should have another
reference and the iput() at line 2070 should not be the final iput
(dropping the last reference).  So I don't think the inode is really in
the recover list (no vmcore to confirm).

Note that ocfs2_queue_orphans(), though not shown up in the call back
trace, is holding cluster lock on the orphan directory when looking up
for unlinked inodes.  The on disk inode eviction could involve a lot of
IOs which may need long time to finish.  That means this node could hold
the cluster lock for very long time, that can lead to the lock requests
(from other nodes) to the orhpan directory hang for long time.

Looking at more on ip_next_orphan, I found it's not initialized when
allocating a new ocfs2_inode_info structure.

This causes te reflink operations from some nodes hang for very long
time waiting for the cluster lock on the orphan directory.

Fix: initialize ip_next_orphan as NULL.

Signed-off-by: Wengang Wang <wen.gang.wang@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Gang He <ghe@suse.com>
Cc: Jun Piao <piaojun@huawei.com>
Cc: <stable@vger.kernel.org>
Link: https://lkml.kernel.org/r/20201109171746.27884-1-wen.gang.wang@oracle.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2020-11-14 11:26:04 -08:00
..
cluster ocfs2: cleanup o2hb_region_dev_store 2020-09-23 10:43:19 -06:00
dlm ocfs2: add missing annotation for dlm_empty_lockres() 2020-06-02 10:59:05 -07:00
dlmfs dlmfs: clean up dlmfs_file_{read,write}() a bit 2020-06-14 19:04:42 -04:00
acl.c ocfs2: fix remounting needed after setfacl command 2020-08-07 11:33:21 -07:00
acl.h
alloc.c ocfs2: fix potential soft lockup during fstrim 2020-10-13 18:38:27 -07:00
alloc.h
aops.c fs: convert mpage_readpages to mpage_readahead 2020-06-02 10:59:07 -07:00
aops.h
blockcheck.c ocfs2: replace HTTP links with HTTPS ones 2020-08-07 11:33:22 -07:00
blockcheck.h
buffer_head_io.c
buffer_head_io.h
dcache.c
dcache.h
dir.c treewide: Remove uninitialized_var() usage 2020-07-16 12:35:15 -07:00
dir.h
dlmglue.c ocfs2: fix unbalanced locking 2020-08-07 11:33:22 -07:00
dlmglue.h
export.c
export.h
extent_map.c treewide: Remove uninitialized_var() usage 2020-07-16 12:35:15 -07:00
extent_map.h
file.c block: remove the error_sector argument to blkdev_issue_flush 2020-05-22 08:45:46 -06:00
file.h
filecheck.c
filecheck.h
heartbeat.c
heartbeat.h
inode.c
inode.h
ioctl.c compat_ioctl: remove most of fs/compat_ioctl.c 2019-12-01 13:46:15 -08:00
ioctl.h
journal.c jbd2: rename j_maxlen to j_total_len and add jbd2_journal_max_txn_bufs 2020-11-06 23:01:02 -05:00
journal.h ocfs2: fix a NULL pointer dereference when call ocfs2_update_inode_fsync_trans() 2020-01-31 10:30:36 -08:00
Kconfig ocfs2: replace HTTP links with HTTPS ones 2020-08-07 11:33:22 -07:00
localalloc.c ocfs2: delete repeated words in comments 2020-10-13 18:38:27 -07:00
localalloc.h
locks.c
locks.h
Makefile
mmap.c ocfs2: fix spelling mistake and grammar 2020-06-10 19:14:18 -07:00
mmap.h
move_extents.c
move_extents.h
namei.c treewide: Remove uninitialized_var() usage 2020-07-16 12:35:15 -07:00
namei.h
ocfs1_fs_compat.h
ocfs2_fs.h ocfs2: fix value of OCFS2_INVALID_SLOT 2020-06-26 00:27:37 -07:00
ocfs2_ioctl.h
ocfs2_lockid.h
ocfs2_lockingver.h
ocfs2_trace.h
ocfs2.h ocfs2: change slot number type s16 to u16 2020-08-07 11:33:21 -07:00
quota_global.c
quota_local.c
quota.h
refcounttree.c treewide: Remove uninitialized_var() usage 2020-07-16 12:35:15 -07:00
refcounttree.h
reservations.c ocfs2: remove unused macros 2020-04-02 09:35:25 -07:00
reservations.h
resize.c
resize.h
slot_map.c ocfs2: mount shared volume without ha stack 2020-06-02 10:59:05 -07:00
slot_map.h
stack_o2cb.c
stack_user.c
stackglue.c ocfs2: remove FS_OCFS2_NM 2020-04-02 09:35:25 -07:00
stackglue.h
suballoc.c ocfs2: change slot number type s16 to u16 2020-08-07 11:33:21 -07:00
suballoc.h ocfs2: suballoc.h: delete a duplicated word 2020-08-07 11:33:21 -07:00
super.c ocfs2: initialize ip_next_orphan 2020-11-14 11:26:04 -08:00
super.h
symlink.c
symlink.h
sysfile.c
sysfile.h
uptodate.c
uptodate.h
xattr.c treewide: Remove uninitialized_var() usage 2020-07-16 12:35:15 -07:00
xattr.h