mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-03-16 03:54:10 +00:00
for-6.2-rc7-tag
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAmPo41YACgkQxWXV+ddt WDsPXA/8DPCp1PEvmkJ998wBCgSuoVvG9b4l1HOI0aFWC/giJWYsTdBF/+rFP/83 +UFBmxDsbG8tMoq73Dw8XxTvmYwRUyCdtn/AmKkGpu/l9KF4fnM+RTIh94e4DaH7 O1R5zPVOX34ScgL/bR6Hmcrw8a7q6yUmW9xORR40AAbYOccUld4nvUZOI+hVUbtN 84pphG+U4KowtX2J4fqLWALGU/2hDP9Aiq3aKOdupoiRYJacx3FoMP4aaEblJlMk ViLJYBXrJ+6v71frjT4LgSdDd7+l6QEaHHlQwIxMrf3r7AXUkMerwoiOhasMRXTB WnZjC8XeS9yogY6Ls5/gIEEWB7buz6TFJwm3rwfXMM+0OQ1g0RFvjXQPD8sOLazS X/5ToML8SZYpfkmIMnP+hBnmAMFKpjC06o40cN5/96xkqqMAwL7ws+XIlso/Hx+l Lu01cgnDLluRflWtVwMLmrhOGLStjbiDJKmG4zKl/WsyqGdodjIUyCOjhB0Wy0CN RMrkvOUwngTfAdWQYTHDdxkTdn1+b/nB+N9BvLbD8Dt+Q5H7loGR+0mS5xsRNg4Q jDY0yLDtR6bDxvcp4L2Vz1ezn+dSo8XAR9zqd4pT+7mZ6tLsf0R5F3iedAZkaqQC 1uVkjiHyi1Gq/6iKRwf72rQMNKdDmAgM+sDx0uQK5JyG8ZGqgLA= =KGNk -----END PGP SIGNATURE----- Merge tag 'for-6.2-rc7-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux Pull btrfs fixes from David Sterba: - one more fix for a tree-log 'write time corruption' report, update the last dir index directly and don't keep in the log context - do VFS-level inode lock around FIEMAP to prevent a deadlock with concurrent fsync, the extent-level lock is not sufficient - don't cache a single-device filesystem device to avoid cases when a loop device is reformatted and the entry gets stale * tag 'for-6.2-rc7-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: free device in btrfs_close_devices for a single device filesystem btrfs: lock the inode in shared mode before starting fiemap btrfs: simplify update of last_dir_index_offset when logging a directory
This commit is contained in:
commit
711e9a4d52
4 changed files with 34 additions and 9 deletions
|
@ -3826,6 +3826,7 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
|
|||
lockend = round_up(start + len, inode->root->fs_info->sectorsize);
|
||||
prev_extent_end = lockstart;
|
||||
|
||||
btrfs_inode_lock(inode, BTRFS_ILOCK_SHARED);
|
||||
lock_extent(&inode->io_tree, lockstart, lockend, &cached_state);
|
||||
|
||||
ret = fiemap_find_last_extent_offset(inode, path, &last_extent_end);
|
||||
|
@ -4019,6 +4020,7 @@ check_eof_delalloc:
|
|||
|
||||
out_unlock:
|
||||
unlock_extent(&inode->io_tree, lockstart, lockend, &cached_state);
|
||||
btrfs_inode_unlock(inode, BTRFS_ILOCK_SHARED);
|
||||
out:
|
||||
free_extent_state(delalloc_cached_state);
|
||||
btrfs_free_backref_share_ctx(backref_ctx);
|
||||
|
|
|
@ -3576,17 +3576,19 @@ static noinline int insert_dir_log_key(struct btrfs_trans_handle *trans,
|
|||
}
|
||||
|
||||
static int flush_dir_items_batch(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *log,
|
||||
struct btrfs_inode *inode,
|
||||
struct extent_buffer *src,
|
||||
struct btrfs_path *dst_path,
|
||||
int start_slot,
|
||||
int count)
|
||||
{
|
||||
struct btrfs_root *log = inode->root->log_root;
|
||||
char *ins_data = NULL;
|
||||
struct btrfs_item_batch batch;
|
||||
struct extent_buffer *dst;
|
||||
unsigned long src_offset;
|
||||
unsigned long dst_offset;
|
||||
u64 last_index;
|
||||
struct btrfs_key key;
|
||||
u32 item_size;
|
||||
int ret;
|
||||
|
@ -3644,6 +3646,19 @@ static int flush_dir_items_batch(struct btrfs_trans_handle *trans,
|
|||
src_offset = btrfs_item_ptr_offset(src, start_slot + count - 1);
|
||||
copy_extent_buffer(dst, src, dst_offset, src_offset, batch.total_data_size);
|
||||
btrfs_release_path(dst_path);
|
||||
|
||||
last_index = batch.keys[count - 1].offset;
|
||||
ASSERT(last_index > inode->last_dir_index_offset);
|
||||
|
||||
/*
|
||||
* If for some unexpected reason the last item's index is not greater
|
||||
* than the last index we logged, warn and return an error to fallback
|
||||
* to a transaction commit.
|
||||
*/
|
||||
if (WARN_ON(last_index <= inode->last_dir_index_offset))
|
||||
ret = -EUCLEAN;
|
||||
else
|
||||
inode->last_dir_index_offset = last_index;
|
||||
out:
|
||||
kfree(ins_data);
|
||||
|
||||
|
@ -3693,7 +3708,6 @@ static int process_dir_items_leaf(struct btrfs_trans_handle *trans,
|
|||
}
|
||||
|
||||
di = btrfs_item_ptr(src, i, struct btrfs_dir_item);
|
||||
ctx->last_dir_item_offset = key.offset;
|
||||
|
||||
/*
|
||||
* Skip ranges of items that consist only of dir item keys created
|
||||
|
@ -3756,7 +3770,7 @@ static int process_dir_items_leaf(struct btrfs_trans_handle *trans,
|
|||
if (batch_size > 0) {
|
||||
int ret;
|
||||
|
||||
ret = flush_dir_items_batch(trans, log, src, dst_path,
|
||||
ret = flush_dir_items_batch(trans, inode, src, dst_path,
|
||||
batch_start, batch_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -4044,7 +4058,6 @@ static noinline int log_directory_changes(struct btrfs_trans_handle *trans,
|
|||
|
||||
min_key = BTRFS_DIR_START_INDEX;
|
||||
max_key = 0;
|
||||
ctx->last_dir_item_offset = inode->last_dir_index_offset;
|
||||
|
||||
while (1) {
|
||||
ret = log_dir_items(trans, inode, path, dst_path,
|
||||
|
@ -4056,8 +4069,6 @@ static noinline int log_directory_changes(struct btrfs_trans_handle *trans,
|
|||
min_key = max_key + 1;
|
||||
}
|
||||
|
||||
inode->last_dir_index_offset = ctx->last_dir_item_offset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,6 @@ struct btrfs_log_ctx {
|
|||
bool logging_new_delayed_dentries;
|
||||
/* Indicate if the inode being logged was logged before. */
|
||||
bool logged_before;
|
||||
/* Tracks the last logged dir item/index key offset. */
|
||||
u64 last_dir_item_offset;
|
||||
struct inode *inode;
|
||||
struct list_head list;
|
||||
/* Only used for fast fsyncs. */
|
||||
|
|
|
@ -403,6 +403,7 @@ void btrfs_free_device(struct btrfs_device *device)
|
|||
static void free_fs_devices(struct btrfs_fs_devices *fs_devices)
|
||||
{
|
||||
struct btrfs_device *device;
|
||||
|
||||
WARN_ON(fs_devices->opened);
|
||||
while (!list_empty(&fs_devices->devices)) {
|
||||
device = list_entry(fs_devices->devices.next,
|
||||
|
@ -1181,9 +1182,22 @@ void btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
|
|||
|
||||
mutex_lock(&uuid_mutex);
|
||||
close_fs_devices(fs_devices);
|
||||
if (!fs_devices->opened)
|
||||
if (!fs_devices->opened) {
|
||||
list_splice_init(&fs_devices->seed_list, &list);
|
||||
|
||||
/*
|
||||
* If the struct btrfs_fs_devices is not assembled with any
|
||||
* other device, it can be re-initialized during the next mount
|
||||
* without the needing device-scan step. Therefore, it can be
|
||||
* fully freed.
|
||||
*/
|
||||
if (fs_devices->num_devices == 1) {
|
||||
list_del(&fs_devices->fs_list);
|
||||
free_fs_devices(fs_devices);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
list_for_each_entry_safe(fs_devices, tmp, &list, seed_list) {
|
||||
close_fs_devices(fs_devices);
|
||||
list_del(&fs_devices->seed_list);
|
||||
|
|
Loading…
Add table
Reference in a new issue