Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bcachefs: Pass inode bkey to check_path()

prep work for improving logging/error messages

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>

+40 -29
+26 -29
fs/bcachefs/fsck.c
··· 2105 2105 * 2106 2106 * XXX: we should also be verifying that inodes are in the right subvolumes 2107 2107 */ 2108 - static int check_path(struct btree_trans *trans, 2109 - pathbuf *p, 2110 - struct bch_inode_unpacked *inode, 2111 - u32 snapshot) 2108 + static int check_path(struct btree_trans *trans, pathbuf *p, struct bkey_s_c inode_k) 2112 2109 { 2113 2110 struct bch_fs *c = trans->c; 2111 + struct bch_inode_unpacked inode; 2112 + u32 snapshot = bch2_snapshot_equiv(c, inode_k.k->p.snapshot); 2114 2113 int ret = 0; 2115 2114 2116 - snapshot = bch2_snapshot_equiv(c, snapshot); 2117 2115 p->nr = 0; 2118 2116 2119 - while (!(inode->bi_inum == BCACHEFS_ROOT_INO && 2120 - inode->bi_subvol == BCACHEFS_ROOT_SUBVOL)) { 2117 + BUG_ON(bch2_inode_unpack(inode_k, &inode)); 2118 + 2119 + while (!(inode.bi_inum == BCACHEFS_ROOT_INO && 2120 + inode.bi_subvol == BCACHEFS_ROOT_SUBVOL)) { 2121 2121 struct btree_iter dirent_iter; 2122 2122 struct bkey_s_c_dirent d; 2123 2123 u32 parent_snapshot = snapshot; 2124 2124 2125 - d = inode_get_dirent(trans, &dirent_iter, inode, &parent_snapshot); 2125 + d = inode_get_dirent(trans, &dirent_iter, &inode, &parent_snapshot); 2126 2126 ret = bkey_err(d.s_c); 2127 2127 if (ret && !bch2_err_matches(ret, ENOENT)) 2128 2128 break; 2129 2129 2130 - if (!ret && !dirent_points_to_inode(d, inode)) { 2130 + if (!ret && !dirent_points_to_inode(d, &inode)) { 2131 2131 bch2_trans_iter_exit(trans, &dirent_iter); 2132 2132 ret = -BCH_ERR_ENOENT_dirent_doesnt_match_inode; 2133 2133 } 2134 2134 2135 2135 if (bch2_err_matches(ret, ENOENT)) { 2136 - if (fsck_err(c, inode_unreachable, 2136 + if (fsck_err(c, inode_unreachable, 2137 2137 "unreachable inode %llu:%u, type %s nlink %u backptr %llu:%llu", 2138 - inode->bi_inum, snapshot, 2139 - bch2_d_type_str(inode_d_type(inode)), 2140 - inode->bi_nlink, 2141 - inode->bi_dir, 2142 - inode->bi_dir_offset)) 2143 - ret = reattach_inode(trans, inode, snapshot); 2138 + inode.bi_inum, snapshot, 2139 + bch2_d_type_str(inode_d_type(&inode)), 2140 + inode.bi_nlink, 2141 + inode.bi_dir, 2142 + inode.bi_dir_offset)) 2143 + ret = reattach_inode(trans, &inode, snapshot); 2144 2144 break; 2145 2145 } 2146 2146 2147 2147 bch2_trans_iter_exit(trans, &dirent_iter); 2148 2148 2149 - if (!S_ISDIR(inode->bi_mode)) 2149 + if (!S_ISDIR(inode.bi_mode)) 2150 2150 break; 2151 2151 2152 - ret = path_down(c, p, inode->bi_inum, snapshot); 2152 + ret = path_down(c, p, inode.bi_inum, snapshot); 2153 2153 if (ret) { 2154 2154 bch_err(c, "memory allocation failure"); 2155 2155 return ret; ··· 2157 2157 2158 2158 snapshot = parent_snapshot; 2159 2159 2160 - ret = lookup_inode(trans, inode->bi_dir, inode, &snapshot); 2160 + ret = lookup_inode(trans, inode.bi_dir, &inode, &snapshot); 2161 2161 if (ret) { 2162 2162 /* Should have been caught in dirents pass */ 2163 2163 if (!bch2_err_matches(ret, BCH_ERR_transaction_restart)) ··· 2165 2165 break; 2166 2166 } 2167 2167 2168 - if (path_is_dup(p, inode->bi_inum, snapshot)) { 2168 + if (path_is_dup(p, inode.bi_inum, snapshot)) { 2169 2169 /* XXX print path */ 2170 2170 bch_err(c, "directory structure loop"); 2171 2171 2172 2172 darray_for_each(*p, i) 2173 2173 pr_err("%llu:%u", i->inum, i->snapshot); 2174 - pr_err("%llu:%u", inode->bi_inum, snapshot); 2174 + pr_err("%llu:%u", inode.bi_inum, snapshot); 2175 2175 2176 2176 if (!fsck_err(c, dir_loop, "directory structure loop")) 2177 2177 return 0; 2178 2178 2179 - ret = remove_backpointer(trans, inode); 2179 + ret = remove_backpointer(trans, &inode); 2180 2180 if (ret && !bch2_err_matches(ret, BCH_ERR_transaction_restart)) 2181 2181 bch_err_msg(c, ret, "removing dirent"); 2182 2182 if (ret) 2183 2183 break; 2184 2184 2185 - ret = reattach_inode(trans, inode, snapshot); 2185 + ret = reattach_inode(trans, &inode, snapshot); 2186 2186 if (ret && !bch2_err_matches(ret, BCH_ERR_transaction_restart)) 2187 - bch_err_msg(c, ret, "reattaching inode %llu", inode->bi_inum); 2187 + bch_err_msg(c, ret, "reattaching inode %llu", inode.bi_inum); 2188 2188 break; 2189 2189 } 2190 2190 } ··· 2200 2200 */ 2201 2201 int bch2_check_directory_structure(struct bch_fs *c) 2202 2202 { 2203 - struct bch_inode_unpacked u; 2204 2203 pathbuf path = { 0, }; 2205 2204 int ret; 2206 2205 ··· 2212 2213 if (!bkey_is_inode(k.k)) 2213 2214 continue; 2214 2215 2215 - BUG_ON(bch2_inode_unpack(k, &u)); 2216 - 2217 - if (u.bi_flags & BCH_INODE_unlinked) 2216 + if (bch2_inode_flags(k) & BCH_INODE_unlinked) 2218 2217 continue; 2219 2218 2220 - check_path(trans, &path, &u, iter.pos.snapshot); 2219 + check_path(trans, &path, k); 2221 2220 }))); 2222 2221 darray_exit(&path); 2223 2222
+14
fs/bcachefs/inode.h
··· 177 177 return inode->bi_subvol ? DT_SUBVOL : mode_to_type(inode->bi_mode); 178 178 } 179 179 180 + static inline u32 bch2_inode_flags(struct bkey_s_c k) 181 + { 182 + switch (k.k->type) { 183 + case KEY_TYPE_inode: 184 + return le32_to_cpu(bkey_s_c_to_inode(k).v->bi_flags); 185 + case KEY_TYPE_inode_v2: 186 + return le64_to_cpu(bkey_s_c_to_inode_v2(k).v->bi_flags); 187 + case KEY_TYPE_inode_v3: 188 + return le64_to_cpu(bkey_s_c_to_inode_v3(k).v->bi_flags); 189 + default: 190 + return 0; 191 + } 192 + } 193 + 180 194 /* i_nlink: */ 181 195 182 196 static inline unsigned nlink_bias(umode_t mode)