Skip to content

Commit d532dd1

Browse files
committed
Merge tag 'for-6.2-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: "Another batch of fixes, dealing with fallouts from 6.1 reported by users: - tree-log fixes: - fix directory logging due to race with concurrent index key deletion - fix missing error handling when logging directory items - handle case of conflicting inodes being added to the log - remove transaction aborts for not so serious errors - fix qgroup accounting warning when rescan can be started at time with temporarily disable accounting - print more specific errors to system log when device scan ioctl fails - disable space overcommit for ZNS devices, causing heavy performance drop" * tag 'for-6.2-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: do not abort transaction on failure to update log root btrfs: do not abort transaction on failure to write log tree when syncing log btrfs: add missing setup of log for full commit at add_conflicting_inode() btrfs: fix directory logging due to race with concurrent index key deletion btrfs: fix missing error handling when logging directory items btrfs: zoned: enable metadata over-commit for non-ZNS setup btrfs: qgroup: do not warn on record without old_roots populated btrfs: add extra error messages to cover non-ENOMEM errors from device_add_list()
2 parents 5dc4c99 + 09e4486 commit d532dd1

File tree

7 files changed

+71
-21
lines changed

7 files changed

+71
-21
lines changed

fs/btrfs/disk-io.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,14 @@ static int csum_one_extent_buffer(struct extent_buffer *eb)
367367
btrfs_print_tree(eb, 0);
368368
btrfs_err(fs_info, "block=%llu write time tree block corruption detected",
369369
eb->start);
370-
WARN_ON(IS_ENABLED(CONFIG_BTRFS_DEBUG));
370+
/*
371+
* Be noisy if this is an extent buffer from a log tree. We don't abort
372+
* a transaction in case there's a bad log tree extent buffer, we just
373+
* fallback to a transaction commit. Still we want to know when there is
374+
* a bad log tree extent buffer, as that may signal a bug somewhere.
375+
*/
376+
WARN_ON(IS_ENABLED(CONFIG_BTRFS_DEBUG) ||
377+
btrfs_header_owner(eb) == BTRFS_TREE_LOG_OBJECTID);
371378
return ret;
372379
}
373380

fs/btrfs/fs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,12 @@ enum {
119119
/* Indicate that we want to commit the transaction. */
120120
BTRFS_FS_NEED_TRANS_COMMIT,
121121

122+
/*
123+
* Indicate metadata over-commit is disabled. This is set when active
124+
* zone tracking is needed.
125+
*/
126+
BTRFS_FS_NO_OVERCOMMIT,
127+
122128
#if BITS_PER_LONG == 32
123129
/* Indicate if we have error/warn message printed on 32bit systems */
124130
BTRFS_FS_32BIT_ERROR,

fs/btrfs/qgroup.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2765,9 +2765,19 @@ int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans)
27652765

27662766
/*
27672767
* Old roots should be searched when inserting qgroup
2768-
* extent record
2768+
* extent record.
2769+
*
2770+
* But for INCONSISTENT (NO_ACCOUNTING) -> rescan case,
2771+
* we may have some record inserted during
2772+
* NO_ACCOUNTING (thus no old_roots populated), but
2773+
* later we start rescan, which clears NO_ACCOUNTING,
2774+
* leaving some inserted records without old_roots
2775+
* populated.
2776+
*
2777+
* Those cases are rare and should not cause too much
2778+
* time spent during commit_transaction().
27692779
*/
2770-
if (WARN_ON(!record->old_roots)) {
2780+
if (!record->old_roots) {
27712781
/* Search commit root to find old_roots */
27722782
ret = btrfs_find_all_roots(&ctx, false);
27732783
if (ret < 0)

fs/btrfs/space-info.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,8 @@ int btrfs_can_overcommit(struct btrfs_fs_info *fs_info,
407407
return 0;
408408

409409
used = btrfs_space_info_used(space_info, true);
410-
if (btrfs_is_zoned(fs_info) && (space_info->flags & BTRFS_BLOCK_GROUP_METADATA))
410+
if (test_bit(BTRFS_FS_NO_OVERCOMMIT, &fs_info->flags) &&
411+
(space_info->flags & BTRFS_BLOCK_GROUP_METADATA))
411412
avail = 0;
412413
else
413414
avail = calc_available_free_space(fs_info, space_info, flush);

fs/btrfs/tree-log.c

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2980,7 +2980,6 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
29802980
ret = 0;
29812981
if (ret) {
29822982
blk_finish_plug(&plug);
2983-
btrfs_abort_transaction(trans, ret);
29842983
btrfs_set_log_full_commit(trans);
29852984
mutex_unlock(&root->log_mutex);
29862985
goto out;
@@ -3045,15 +3044,12 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
30453044

30463045
blk_finish_plug(&plug);
30473046
btrfs_set_log_full_commit(trans);
3048-
3049-
if (ret != -ENOSPC) {
3050-
btrfs_abort_transaction(trans, ret);
3051-
mutex_unlock(&log_root_tree->log_mutex);
3052-
goto out;
3053-
}
3047+
if (ret != -ENOSPC)
3048+
btrfs_err(fs_info,
3049+
"failed to update log for root %llu ret %d",
3050+
root->root_key.objectid, ret);
30543051
btrfs_wait_tree_log_extents(log, mark);
30553052
mutex_unlock(&log_root_tree->log_mutex);
3056-
ret = BTRFS_LOG_FORCE_COMMIT;
30573053
goto out;
30583054
}
30593055

@@ -3112,7 +3108,6 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
31123108
goto out_wake_log_root;
31133109
} else if (ret) {
31143110
btrfs_set_log_full_commit(trans);
3115-
btrfs_abort_transaction(trans, ret);
31163111
mutex_unlock(&log_root_tree->log_mutex);
31173112
goto out_wake_log_root;
31183113
}
@@ -3826,7 +3821,10 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans,
38263821
path->slots[0]);
38273822
if (tmp.type == BTRFS_DIR_INDEX_KEY)
38283823
last_old_dentry_offset = tmp.offset;
3824+
} else if (ret < 0) {
3825+
err = ret;
38293826
}
3827+
38303828
goto done;
38313829
}
38323830

@@ -3846,19 +3844,34 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans,
38463844
*/
38473845
if (tmp.type == BTRFS_DIR_INDEX_KEY)
38483846
last_old_dentry_offset = tmp.offset;
3847+
} else if (ret < 0) {
3848+
err = ret;
3849+
goto done;
38493850
}
3851+
38503852
btrfs_release_path(path);
38513853

38523854
/*
3853-
* Find the first key from this transaction again. See the note for
3854-
* log_new_dir_dentries, if we're logging a directory recursively we
3855-
* won't be holding its i_mutex, which means we can modify the directory
3856-
* while we're logging it. If we remove an entry between our first
3857-
* search and this search we'll not find the key again and can just
3858-
* bail.
3855+
* Find the first key from this transaction again or the one we were at
3856+
* in the loop below in case we had to reschedule. We may be logging the
3857+
* directory without holding its VFS lock, which happen when logging new
3858+
* dentries (through log_new_dir_dentries()) or in some cases when we
3859+
* need to log the parent directory of an inode. This means a dir index
3860+
* key might be deleted from the inode's root, and therefore we may not
3861+
* find it anymore. If we can't find it, just move to the next key. We
3862+
* can not bail out and ignore, because if we do that we will simply
3863+
* not log dir index keys that come after the one that was just deleted
3864+
* and we can end up logging a dir index range that ends at (u64)-1
3865+
* (@last_offset is initialized to that), resulting in removing dir
3866+
* entries we should not remove at log replay time.
38593867
*/
38603868
search:
38613869
ret = btrfs_search_slot(NULL, root, &min_key, path, 0, 0);
3870+
if (ret > 0)
3871+
ret = btrfs_next_item(root, path);
3872+
if (ret < 0)
3873+
err = ret;
3874+
/* If ret is 1, there are no more keys in the inode's root. */
38623875
if (ret != 0)
38633876
goto done;
38643877

@@ -5580,8 +5593,10 @@ static int add_conflicting_inode(struct btrfs_trans_handle *trans,
55805593
* LOG_INODE_EXISTS mode) and slow down other fsyncs or transaction
55815594
* commits.
55825595
*/
5583-
if (ctx->num_conflict_inodes >= MAX_CONFLICT_INODES)
5596+
if (ctx->num_conflict_inodes >= MAX_CONFLICT_INODES) {
5597+
btrfs_set_log_full_commit(trans);
55845598
return BTRFS_LOG_FORCE_COMMIT;
5599+
}
55855600

55865601
inode = btrfs_iget(root->fs_info->sb, ino, root);
55875602
/*

fs/btrfs/volumes.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -768,8 +768,11 @@ static noinline struct btrfs_device *device_list_add(const char *path,
768768
BTRFS_SUPER_FLAG_CHANGING_FSID_V2);
769769

770770
error = lookup_bdev(path, &path_devt);
771-
if (error)
771+
if (error) {
772+
btrfs_err(NULL, "failed to lookup block device for path %s: %d",
773+
path, error);
772774
return ERR_PTR(error);
775+
}
773776

774777
if (fsid_change_in_progress) {
775778
if (!has_metadata_uuid)
@@ -836,6 +839,9 @@ static noinline struct btrfs_device *device_list_add(const char *path,
836839
unsigned int nofs_flag;
837840

838841
if (fs_devices->opened) {
842+
btrfs_err(NULL,
843+
"device %s belongs to fsid %pU, and the fs is already mounted",
844+
path, fs_devices->fsid);
839845
mutex_unlock(&fs_devices->device_list_mutex);
840846
return ERR_PTR(-EBUSY);
841847
}
@@ -905,6 +911,9 @@ static noinline struct btrfs_device *device_list_add(const char *path,
905911
* generation are equal.
906912
*/
907913
mutex_unlock(&fs_devices->device_list_mutex);
914+
btrfs_err(NULL,
915+
"device %s already registered with a higher generation, found %llu expect %llu",
916+
path, found_transid, device->generation);
908917
return ERR_PTR(-EEXIST);
909918
}
910919

fs/btrfs/zoned.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,8 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache)
539539
}
540540
atomic_set(&zone_info->active_zones_left,
541541
max_active_zones - nactive);
542+
/* Overcommit does not work well with active zone tacking. */
543+
set_bit(BTRFS_FS_NO_OVERCOMMIT, &fs_info->flags);
542544
}
543545

544546
/* Validate superblock log */

0 commit comments

Comments
 (0)