.. | .. |
---|
121 | 121 | * An item with that type already exists. |
---|
122 | 122 | * Extend the item and store the new subid at the end. |
---|
123 | 123 | */ |
---|
124 | | - btrfs_extend_item(fs_info, path, sizeof(subid_le)); |
---|
| 124 | + btrfs_extend_item(path, sizeof(subid_le)); |
---|
125 | 125 | eb = path->nodes[0]; |
---|
126 | 126 | slot = path->slots[0]; |
---|
127 | 127 | offset = btrfs_item_ptr_offset(eb, slot); |
---|
128 | 128 | offset += btrfs_item_size_nr(eb, slot) - sizeof(subid_le); |
---|
129 | | - } else if (ret < 0) { |
---|
| 129 | + } else { |
---|
130 | 130 | btrfs_warn(fs_info, |
---|
131 | 131 | "insert uuid item failed %d (0x%016llx, 0x%016llx) type %u!", |
---|
132 | 132 | ret, (unsigned long long)key.objectid, |
---|
.. | .. |
---|
219 | 219 | move_src = offset + sizeof(subid); |
---|
220 | 220 | move_len = item_size - (move_src - btrfs_item_ptr_offset(eb, slot)); |
---|
221 | 221 | memmove_extent_buffer(eb, move_dst, move_src, move_len); |
---|
222 | | - btrfs_truncate_item(fs_info, path, item_size - sizeof(subid), 1); |
---|
| 222 | + btrfs_truncate_item(path, item_size - sizeof(subid), 1); |
---|
223 | 223 | |
---|
224 | 224 | out: |
---|
225 | 225 | btrfs_free_path(path); |
---|
.. | .. |
---|
246 | 246 | return ret; |
---|
247 | 247 | } |
---|
248 | 248 | |
---|
249 | | -int btrfs_uuid_tree_iterate(struct btrfs_fs_info *fs_info, |
---|
250 | | - int (*check_func)(struct btrfs_fs_info *, u8 *, u8, |
---|
251 | | - u64)) |
---|
| 249 | +/* |
---|
| 250 | + * Check if there's an matching subvolume for given UUID |
---|
| 251 | + * |
---|
| 252 | + * Return: |
---|
| 253 | + * 0 check succeeded, the entry is not outdated |
---|
| 254 | + * > 0 if the check failed, the caller should remove the entry |
---|
| 255 | + * < 0 if an error occurred |
---|
| 256 | + */ |
---|
| 257 | +static int btrfs_check_uuid_tree_entry(struct btrfs_fs_info *fs_info, |
---|
| 258 | + u8 *uuid, u8 type, u64 subvolid) |
---|
| 259 | +{ |
---|
| 260 | + int ret = 0; |
---|
| 261 | + struct btrfs_root *subvol_root; |
---|
| 262 | + |
---|
| 263 | + if (type != BTRFS_UUID_KEY_SUBVOL && |
---|
| 264 | + type != BTRFS_UUID_KEY_RECEIVED_SUBVOL) |
---|
| 265 | + goto out; |
---|
| 266 | + |
---|
| 267 | + subvol_root = btrfs_get_fs_root(fs_info, subvolid, true); |
---|
| 268 | + if (IS_ERR(subvol_root)) { |
---|
| 269 | + ret = PTR_ERR(subvol_root); |
---|
| 270 | + if (ret == -ENOENT) |
---|
| 271 | + ret = 1; |
---|
| 272 | + goto out; |
---|
| 273 | + } |
---|
| 274 | + |
---|
| 275 | + switch (type) { |
---|
| 276 | + case BTRFS_UUID_KEY_SUBVOL: |
---|
| 277 | + if (memcmp(uuid, subvol_root->root_item.uuid, BTRFS_UUID_SIZE)) |
---|
| 278 | + ret = 1; |
---|
| 279 | + break; |
---|
| 280 | + case BTRFS_UUID_KEY_RECEIVED_SUBVOL: |
---|
| 281 | + if (memcmp(uuid, subvol_root->root_item.received_uuid, |
---|
| 282 | + BTRFS_UUID_SIZE)) |
---|
| 283 | + ret = 1; |
---|
| 284 | + break; |
---|
| 285 | + } |
---|
| 286 | + btrfs_put_root(subvol_root); |
---|
| 287 | +out: |
---|
| 288 | + return ret; |
---|
| 289 | +} |
---|
| 290 | + |
---|
| 291 | +int btrfs_uuid_tree_iterate(struct btrfs_fs_info *fs_info) |
---|
252 | 292 | { |
---|
253 | 293 | struct btrfs_root *root = fs_info->uuid_root; |
---|
254 | 294 | struct btrfs_key key; |
---|
.. | .. |
---|
278 | 318 | } |
---|
279 | 319 | |
---|
280 | 320 | while (1) { |
---|
| 321 | + if (btrfs_fs_closing(fs_info)) { |
---|
| 322 | + ret = -EINTR; |
---|
| 323 | + goto out; |
---|
| 324 | + } |
---|
281 | 325 | cond_resched(); |
---|
282 | 326 | leaf = path->nodes[0]; |
---|
283 | 327 | slot = path->slots[0]; |
---|
.. | .. |
---|
305 | 349 | read_extent_buffer(leaf, &subid_le, offset, |
---|
306 | 350 | sizeof(subid_le)); |
---|
307 | 351 | subid_cpu = le64_to_cpu(subid_le); |
---|
308 | | - ret = check_func(fs_info, uuid, key.type, subid_cpu); |
---|
| 352 | + ret = btrfs_check_uuid_tree_entry(fs_info, uuid, |
---|
| 353 | + key.type, subid_cpu); |
---|
309 | 354 | if (ret < 0) |
---|
310 | 355 | goto out; |
---|
311 | 356 | if (ret > 0) { |
---|