Skip to content

Commit 8d19514

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs fixes from Chris Mason: "We've got corner cases for updating i_size that ceph was hitting, error handling for quotas when we run out of space, a very subtle snapshot deletion race, a crash while removing devices, and one deadlock between subvolume creation and the sb_internal code (thanks lockdep)." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: Btrfs: move d_instantiate outside the transaction during mksubvol Btrfs: fix EDQUOT handling in btrfs_delalloc_reserve_metadata Btrfs: fix possible stale data exposure Btrfs: fix missing i_size update Btrfs: fix race between snapshot deletion and getting inode Btrfs: fix missing release of the space/qgroup reservation in start_transaction() Btrfs: fix wrong sync_writers decrement in btrfs_file_aio_write() Btrfs: do not merge logged extents if we've removed them from the tree btrfs: don't try to notify udev about missing devices
2 parents 95436ad + 1a65e24 commit 8d19514

File tree

8 files changed

+87
-36
lines changed

8 files changed

+87
-36
lines changed

fs/btrfs/extent-tree.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4534,7 +4534,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
45344534
unsigned nr_extents = 0;
45354535
int extra_reserve = 0;
45364536
enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_FLUSH_ALL;
4537-
int ret;
4537+
int ret = 0;
45384538
bool delalloc_lock = true;
45394539

45404540
/* If we are a free space inode we need to not flush since we will be in
@@ -4579,20 +4579,18 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
45794579
csum_bytes = BTRFS_I(inode)->csum_bytes;
45804580
spin_unlock(&BTRFS_I(inode)->lock);
45814581

4582-
if (root->fs_info->quota_enabled) {
4582+
if (root->fs_info->quota_enabled)
45834583
ret = btrfs_qgroup_reserve(root, num_bytes +
45844584
nr_extents * root->leafsize);
4585-
if (ret) {
4586-
spin_lock(&BTRFS_I(inode)->lock);
4587-
calc_csum_metadata_size(inode, num_bytes, 0);
4588-
spin_unlock(&BTRFS_I(inode)->lock);
4589-
if (delalloc_lock)
4590-
mutex_unlock(&BTRFS_I(inode)->delalloc_mutex);
4591-
return ret;
4592-
}
4593-
}
45944585

4595-
ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush);
4586+
/*
4587+
* ret != 0 here means the qgroup reservation failed, we go straight to
4588+
* the shared error handling then.
4589+
*/
4590+
if (ret == 0)
4591+
ret = reserve_metadata_bytes(root, block_rsv,
4592+
to_reserve, flush);
4593+
45964594
if (ret) {
45974595
u64 to_free = 0;
45984596
unsigned dropped;

fs/btrfs/extent_map.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,8 @@ int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len,
288288
void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em)
289289
{
290290
clear_bit(EXTENT_FLAG_LOGGING, &em->flags);
291-
try_merge_map(tree, em);
291+
if (em->in_tree)
292+
try_merge_map(tree, em);
292293
}
293294

294295
/**

fs/btrfs/file.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -293,25 +293,35 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info,
293293
struct btrfs_key key;
294294
struct btrfs_ioctl_defrag_range_args range;
295295
int num_defrag;
296+
int index;
297+
int ret;
296298

297299
/* get the inode */
298300
key.objectid = defrag->root;
299301
btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);
300302
key.offset = (u64)-1;
303+
304+
index = srcu_read_lock(&fs_info->subvol_srcu);
305+
301306
inode_root = btrfs_read_fs_root_no_name(fs_info, &key);
302307
if (IS_ERR(inode_root)) {
303-
kmem_cache_free(btrfs_inode_defrag_cachep, defrag);
304-
return PTR_ERR(inode_root);
308+
ret = PTR_ERR(inode_root);
309+
goto cleanup;
310+
}
311+
if (btrfs_root_refs(&inode_root->root_item) == 0) {
312+
ret = -ENOENT;
313+
goto cleanup;
305314
}
306315

307316
key.objectid = defrag->ino;
308317
btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY);
309318
key.offset = 0;
310319
inode = btrfs_iget(fs_info->sb, &key, inode_root, NULL);
311320
if (IS_ERR(inode)) {
312-
kmem_cache_free(btrfs_inode_defrag_cachep, defrag);
313-
return PTR_ERR(inode);
321+
ret = PTR_ERR(inode);
322+
goto cleanup;
314323
}
324+
srcu_read_unlock(&fs_info->subvol_srcu, index);
315325

316326
/* do a chunk of defrag */
317327
clear_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags);
@@ -346,6 +356,10 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info,
346356

347357
iput(inode);
348358
return 0;
359+
cleanup:
360+
srcu_read_unlock(&fs_info->subvol_srcu, index);
361+
kmem_cache_free(btrfs_inode_defrag_cachep, defrag);
362+
return ret;
349363
}
350364

351365
/*
@@ -1594,9 +1608,10 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
15941608
if (err < 0 && num_written > 0)
15951609
num_written = err;
15961610
}
1597-
out:
1611+
15981612
if (sync)
15991613
atomic_dec(&BTRFS_I(inode)->sync_writers);
1614+
out:
16001615
sb_end_write(inode->i_sb);
16011616
current->backing_dev_info = NULL;
16021617
return num_written ? num_written : err;

fs/btrfs/ioctl.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,6 @@ static noinline int create_subvol(struct btrfs_root *root,
515515

516516
BUG_ON(ret);
517517

518-
d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry));
519518
fail:
520519
if (async_transid) {
521520
*async_transid = trans->transid;
@@ -525,6 +524,10 @@ static noinline int create_subvol(struct btrfs_root *root,
525524
}
526525
if (err && !ret)
527526
ret = err;
527+
528+
if (!ret)
529+
d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry));
530+
528531
return ret;
529532
}
530533

fs/btrfs/ordered-data.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -836,9 +836,16 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
836836
* if the disk i_size is already at the inode->i_size, or
837837
* this ordered extent is inside the disk i_size, we're done
838838
*/
839-
if (disk_i_size == i_size || offset <= disk_i_size) {
839+
if (disk_i_size == i_size)
840+
goto out;
841+
842+
/*
843+
* We still need to update disk_i_size if outstanding_isize is greater
844+
* than disk_i_size.
845+
*/
846+
if (offset <= disk_i_size &&
847+
(!ordered || ordered->outstanding_isize <= disk_i_size))
840848
goto out;
841-
}
842849

843850
/*
844851
* walk backward from this ordered extent to disk_i_size.
@@ -870,7 +877,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
870877
break;
871878
if (test->file_offset >= i_size)
872879
break;
873-
if (test->file_offset >= disk_i_size) {
880+
if (entry_end(test) > disk_i_size) {
874881
/*
875882
* we don't update disk_i_size now, so record this
876883
* undealt i_size. Or we will not know the real

fs/btrfs/scrub.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -580,20 +580,29 @@ static int scrub_fixup_readpage(u64 inum, u64 offset, u64 root, void *fixup_ctx)
580580
int corrected = 0;
581581
struct btrfs_key key;
582582
struct inode *inode = NULL;
583+
struct btrfs_fs_info *fs_info;
583584
u64 end = offset + PAGE_SIZE - 1;
584585
struct btrfs_root *local_root;
586+
int srcu_index;
585587

586588
key.objectid = root;
587589
key.type = BTRFS_ROOT_ITEM_KEY;
588590
key.offset = (u64)-1;
589-
local_root = btrfs_read_fs_root_no_name(fixup->root->fs_info, &key);
590-
if (IS_ERR(local_root))
591+
592+
fs_info = fixup->root->fs_info;
593+
srcu_index = srcu_read_lock(&fs_info->subvol_srcu);
594+
595+
local_root = btrfs_read_fs_root_no_name(fs_info, &key);
596+
if (IS_ERR(local_root)) {
597+
srcu_read_unlock(&fs_info->subvol_srcu, srcu_index);
591598
return PTR_ERR(local_root);
599+
}
592600

593601
key.type = BTRFS_INODE_ITEM_KEY;
594602
key.objectid = inum;
595603
key.offset = 0;
596-
inode = btrfs_iget(fixup->root->fs_info->sb, &key, local_root, NULL);
604+
inode = btrfs_iget(fs_info->sb, &key, local_root, NULL);
605+
srcu_read_unlock(&fs_info->subvol_srcu, srcu_index);
597606
if (IS_ERR(inode))
598607
return PTR_ERR(inode);
599608

@@ -606,7 +615,6 @@ static int scrub_fixup_readpage(u64 inum, u64 offset, u64 root, void *fixup_ctx)
606615
}
607616

608617
if (PageUptodate(page)) {
609-
struct btrfs_fs_info *fs_info;
610618
if (PageDirty(page)) {
611619
/*
612620
* we need to write the data to the defect sector. the
@@ -3180,18 +3188,25 @@ static int copy_nocow_pages_for_inode(u64 inum, u64 offset, u64 root, void *ctx)
31803188
u64 physical_for_dev_replace;
31813189
u64 len;
31823190
struct btrfs_fs_info *fs_info = nocow_ctx->sctx->dev_root->fs_info;
3191+
int srcu_index;
31833192

31843193
key.objectid = root;
31853194
key.type = BTRFS_ROOT_ITEM_KEY;
31863195
key.offset = (u64)-1;
3196+
3197+
srcu_index = srcu_read_lock(&fs_info->subvol_srcu);
3198+
31873199
local_root = btrfs_read_fs_root_no_name(fs_info, &key);
3188-
if (IS_ERR(local_root))
3200+
if (IS_ERR(local_root)) {
3201+
srcu_read_unlock(&fs_info->subvol_srcu, srcu_index);
31893202
return PTR_ERR(local_root);
3203+
}
31903204

31913205
key.type = BTRFS_INODE_ITEM_KEY;
31923206
key.objectid = inum;
31933207
key.offset = 0;
31943208
inode = btrfs_iget(fs_info->sb, &key, local_root, NULL);
3209+
srcu_read_unlock(&fs_info->subvol_srcu, srcu_index);
31953210
if (IS_ERR(inode))
31963211
return PTR_ERR(inode);
31973212

fs/btrfs/transaction.c

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -333,12 +333,14 @@ start_transaction(struct btrfs_root *root, u64 num_items, int type,
333333
&root->fs_info->trans_block_rsv,
334334
num_bytes, flush);
335335
if (ret)
336-
return ERR_PTR(ret);
336+
goto reserve_fail;
337337
}
338338
again:
339339
h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
340-
if (!h)
341-
return ERR_PTR(-ENOMEM);
340+
if (!h) {
341+
ret = -ENOMEM;
342+
goto alloc_fail;
343+
}
342344

343345
/*
344346
* If we are JOIN_NOLOCK we're already committing a transaction and
@@ -365,11 +367,7 @@ start_transaction(struct btrfs_root *root, u64 num_items, int type,
365367
if (ret < 0) {
366368
/* We must get the transaction if we are JOIN_NOLOCK. */
367369
BUG_ON(type == TRANS_JOIN_NOLOCK);
368-
369-
if (type < TRANS_JOIN_NOLOCK)
370-
sb_end_intwrite(root->fs_info->sb);
371-
kmem_cache_free(btrfs_trans_handle_cachep, h);
372-
return ERR_PTR(ret);
370+
goto join_fail;
373371
}
374372

375373
cur_trans = root->fs_info->running_transaction;
@@ -410,6 +408,19 @@ start_transaction(struct btrfs_root *root, u64 num_items, int type,
410408
if (!current->journal_info && type != TRANS_USERSPACE)
411409
current->journal_info = h;
412410
return h;
411+
412+
join_fail:
413+
if (type < TRANS_JOIN_NOLOCK)
414+
sb_end_intwrite(root->fs_info->sb);
415+
kmem_cache_free(btrfs_trans_handle_cachep, h);
416+
alloc_fail:
417+
if (num_bytes)
418+
btrfs_block_rsv_release(root, &root->fs_info->trans_block_rsv,
419+
num_bytes);
420+
reserve_fail:
421+
if (qgroup_reserved)
422+
btrfs_qgroup_free(root, qgroup_reserved);
423+
return ERR_PTR(ret);
413424
}
414425

415426
struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,

fs/btrfs/volumes.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1556,7 +1556,8 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
15561556
ret = 0;
15571557

15581558
/* Notify udev that device has changed */
1559-
btrfs_kobject_uevent(bdev, KOBJ_CHANGE);
1559+
if (bdev)
1560+
btrfs_kobject_uevent(bdev, KOBJ_CHANGE);
15601561

15611562
error_brelse:
15621563
brelse(bh);

0 commit comments

Comments
 (0)