hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/fs/btrfs/disk-io.c
....@@ -220,7 +220,7 @@
220220 crypto_shash_update(shash, kaddr + BTRFS_CSUM_SIZE,
221221 PAGE_SIZE - BTRFS_CSUM_SIZE);
222222
223
- for (i = 1; i < num_pages; i++) {
223
+ for (i = 1; i < num_pages && INLINE_EXTENT_BUFFER_PAGES > 1; i++) {
224224 kaddr = page_address(buf->pages[i]);
225225 crypto_shash_update(shash, kaddr, PAGE_SIZE);
226226 }
....@@ -2246,6 +2246,26 @@
22462246
22472247 fs_info->csum_shash = csum_shash;
22482248
2249
+ /*
2250
+ * Check if the checksum implementation is a fast accelerated one.
2251
+ * As-is this is a bit of a hack and should be replaced once the csum
2252
+ * implementations provide that information themselves.
2253
+ */
2254
+ switch (csum_type) {
2255
+ case BTRFS_CSUM_TYPE_CRC32:
2256
+ if (!strstr(crypto_shash_driver_name(csum_shash), "generic"))
2257
+ set_bit(BTRFS_FS_CSUM_IMPL_FAST, &fs_info->flags);
2258
+ break;
2259
+ case BTRFS_CSUM_TYPE_XXHASH:
2260
+ set_bit(BTRFS_FS_CSUM_IMPL_FAST, &fs_info->flags);
2261
+ break;
2262
+ default:
2263
+ break;
2264
+ }
2265
+
2266
+ btrfs_info(fs_info, "using %s (%s) checksum algorithm",
2267
+ btrfs_super_csum_name(csum_type),
2268
+ crypto_shash_driver_name(csum_shash));
22492269 return 0;
22502270 }
22512271
....@@ -2476,21 +2496,18 @@
24762496 ret = -EINVAL;
24772497 }
24782498
2479
- if (memcmp(fs_info->fs_devices->fsid, fs_info->super_copy->fsid,
2480
- BTRFS_FSID_SIZE)) {
2499
+ if (memcmp(fs_info->fs_devices->fsid, sb->fsid, BTRFS_FSID_SIZE) != 0) {
24812500 btrfs_err(fs_info,
24822501 "superblock fsid doesn't match fsid of fs_devices: %pU != %pU",
2483
- fs_info->super_copy->fsid, fs_info->fs_devices->fsid);
2502
+ sb->fsid, fs_info->fs_devices->fsid);
24842503 ret = -EINVAL;
24852504 }
24862505
2487
- if (btrfs_fs_incompat(fs_info, METADATA_UUID) &&
2488
- memcmp(fs_info->fs_devices->metadata_uuid,
2489
- fs_info->super_copy->metadata_uuid, BTRFS_FSID_SIZE)) {
2506
+ if (memcmp(fs_info->fs_devices->metadata_uuid, btrfs_sb_fsid_ptr(sb),
2507
+ BTRFS_FSID_SIZE) != 0) {
24902508 btrfs_err(fs_info,
24912509 "superblock metadata_uuid doesn't match metadata uuid of fs_devices: %pU != %pU",
2492
- fs_info->super_copy->metadata_uuid,
2493
- fs_info->fs_devices->metadata_uuid);
2510
+ btrfs_sb_fsid_ptr(sb), fs_info->fs_devices->metadata_uuid);
24942511 ret = -EINVAL;
24952512 }
24962513
....@@ -4518,7 +4535,11 @@
45184535 */
45194536 inode = igrab(&btrfs_inode->vfs_inode);
45204537 if (inode) {
4538
+ unsigned int nofs_flag;
4539
+
4540
+ nofs_flag = memalloc_nofs_save();
45214541 invalidate_inode_pages2(inode->i_mapping);
4542
+ memalloc_nofs_restore(nofs_flag);
45224543 iput(inode);
45234544 }
45244545 spin_lock(&root->delalloc_lock);
....@@ -4623,7 +4644,12 @@
46234644
46244645 inode = cache->io_ctl.inode;
46254646 if (inode) {
4647
+ unsigned int nofs_flag;
4648
+
4649
+ nofs_flag = memalloc_nofs_save();
46264650 invalidate_inode_pages2(inode->i_mapping);
4651
+ memalloc_nofs_restore(nofs_flag);
4652
+
46274653 BTRFS_I(inode)->generation = 0;
46284654 cache->io_ctl.inode = NULL;
46294655 iput(inode);
....@@ -4763,3 +4789,58 @@
47634789
47644790 return 0;
47654791 }
4792
+
4793
+int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid)
4794
+{
4795
+ struct btrfs_path *path;
4796
+ int ret;
4797
+ struct extent_buffer *l;
4798
+ struct btrfs_key search_key;
4799
+ struct btrfs_key found_key;
4800
+ int slot;
4801
+
4802
+ path = btrfs_alloc_path();
4803
+ if (!path)
4804
+ return -ENOMEM;
4805
+
4806
+ search_key.objectid = BTRFS_LAST_FREE_OBJECTID;
4807
+ search_key.type = -1;
4808
+ search_key.offset = (u64)-1;
4809
+ ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
4810
+ if (ret < 0)
4811
+ goto error;
4812
+ BUG_ON(ret == 0); /* Corruption */
4813
+ if (path->slots[0] > 0) {
4814
+ slot = path->slots[0] - 1;
4815
+ l = path->nodes[0];
4816
+ btrfs_item_key_to_cpu(l, &found_key, slot);
4817
+ *objectid = max_t(u64, found_key.objectid,
4818
+ BTRFS_FIRST_FREE_OBJECTID - 1);
4819
+ } else {
4820
+ *objectid = BTRFS_FIRST_FREE_OBJECTID - 1;
4821
+ }
4822
+ ret = 0;
4823
+error:
4824
+ btrfs_free_path(path);
4825
+ return ret;
4826
+}
4827
+
4828
+int btrfs_find_free_objectid(struct btrfs_root *root, u64 *objectid)
4829
+{
4830
+ int ret;
4831
+ mutex_lock(&root->objectid_mutex);
4832
+
4833
+ if (unlikely(root->highest_objectid >= BTRFS_LAST_FREE_OBJECTID)) {
4834
+ btrfs_warn(root->fs_info,
4835
+ "the objectid of root %llu reaches its highest value",
4836
+ root->root_key.objectid);
4837
+ ret = -ENOSPC;
4838
+ goto out;
4839
+ }
4840
+
4841
+ *objectid = ++root->highest_objectid;
4842
+ ret = 0;
4843
+out:
4844
+ mutex_unlock(&root->objectid_mutex);
4845
+ return ret;
4846
+}