tree: https://github.com/osandov/linux.git btrfs-thp-defrag-fix head: 39c9507c4eca68030bd65cab791db0aaf5314360 commit: 39c9507c4eca68030bd65cab791db0aaf5314360 [1/1] btrfs: fix deadlock when defragging transparent huge pages config: x86_64-randconfig-r004-20211019 (attached as .config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 92a0389b0425a9535a99a0ce13ba0eeda2bce7ad) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/osandov/linux/commit/39c9507c4eca68030bd65cab791db0aaf5314360 git remote add osandov https://github.com/osandov/linux.git git fetch --no-tags osandov btrfs-thp-defrag-fix git checkout 39c9507c4eca68030bd65cab791db0aaf5314360 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=x86_64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): >> fs/btrfs/ioctl.c:1083:10: warning: incompatible integer to pointer conversion returning 'int' from a function with result type 'struct page *' [-Wint-conversion] return -ETXTBSY; ^~~~~~~~ 1 warning generated. vim +1083 fs/btrfs/ioctl.c 1043 1044 /* 1045 * Prepare one page to be defragged. 1046 * 1047 * This will ensure: 1048 * 1049 * - Returned page is locked and has been set up properly. 1050 * - No ordered extent exists in the page. 1051 * - The page is uptodate. 1052 * 1053 * NOTE: Caller should also wait for page writeback after the cluster is 1054 * prepared, here we don't do writeback wait for each page. 1055 */ 1056 static struct page *defrag_prepare_one_page(struct btrfs_inode *inode, 1057 pgoff_t index) 1058 { 1059 struct address_space *mapping = inode->vfs_inode.i_mapping; 1060 gfp_t mask = btrfs_alloc_write_mask(mapping); 1061 u64 page_start = (u64)index << PAGE_SHIFT; 1062 u64 page_end = page_start + PAGE_SIZE - 1; 1063 struct extent_state *cached_state = NULL; 1064 struct page *page; 1065 int ret; 1066 1067 again: 1068 page = find_or_create_page(mapping, index, mask); 1069 if (!page) 1070 return ERR_PTR(-ENOMEM); 1071 1072 /* 1073 * Since we can defragment files opened read-only, we can encounter 1074 * transparent huge pages here (see CONFIG_READ_ONLY_THP_FOR_FS). We 1075 * can't do I/O using huge pages yet, so return an error for now. 1076 * Filesystem transparent huge pages are typically only used for 1077 * executables that explicitly enable them, so this isn't very 1078 * restrictive. 1079 */ 1080 if (PageCompound(page)) { 1081 unlock_page(page); 1082 put_page(page); > 1083 return -ETXTBSY; 1084 } 1085 1086 ret = set_page_extent_mapped(page); 1087 if (ret < 0) { 1088 unlock_page(page); 1089 put_page(page); 1090 return ERR_PTR(ret); 1091 } 1092 1093 /* Wait for any existing ordered extent in the range */ 1094 while (1) { 1095 struct btrfs_ordered_extent *ordered; 1096 1097 lock_extent_bits(&inode->io_tree, page_start, page_end, &cached_state); 1098 ordered = btrfs_lookup_ordered_range(inode, page_start, PAGE_SIZE); 1099 unlock_extent_cached(&inode->io_tree, page_start, page_end, 1100 &cached_state); 1101 if (!ordered) 1102 break; 1103 1104 unlock_page(page); 1105 btrfs_start_ordered_extent(ordered, 1); 1106 btrfs_put_ordered_extent(ordered); 1107 lock_page(page); 1108 /* 1109 * We unlocked the page above, so we need check if it was 1110 * released or not. 1111 */ 1112 if (page->mapping != mapping || !PagePrivate(page)) { 1113 unlock_page(page); 1114 put_page(page); 1115 goto again; 1116 } 1117 } 1118 1119 /* 1120 * Now the page range has no ordered extent any more. Read the page to 1121 * make it uptodate. 1122 */ 1123 if (!PageUptodate(page)) { 1124 btrfs_readpage(NULL, page); 1125 lock_page(page); 1126 if (page->mapping != mapping || !PagePrivate(page)) { 1127 unlock_page(page); 1128 put_page(page); 1129 goto again; 1130 } 1131 if (!PageUptodate(page)) { 1132 unlock_page(page); 1133 put_page(page); 1134 return ERR_PTR(-EIO); 1135 } 1136 } 1137 return page; 1138 } 1139 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org