summaryrefslogtreecommitdiff
path: root/fs/bcachefs/extents.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/bcachefs/extents.c')
-rw-r--r--fs/bcachefs/extents.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
index b879a586b7f6..68a61f7bc737 100644
--- a/fs/bcachefs/extents.c
+++ b/fs/bcachefs/extents.c
@@ -157,7 +157,7 @@ static inline bool ptr_better(struct bch_fs *c,
const struct extent_ptr_decoded p2,
u64 p2_latency)
{
- struct bch_dev *ca2 = bch2_dev_rcu(c, p2.ptr.dev);
+ struct bch_dev *ca2 = bch2_dev_rcu_noerror(c, p2.ptr.dev);
int failed_delta = dev_failed(ca1) - dev_failed(ca2);
if (unlikely(failed_delta))
@@ -419,7 +419,7 @@ bool bch2_extent_merge(struct bch_fs *c, struct bkey_s l, struct bkey_s_c r)
return false;
/* Extents may not straddle buckets: */
- struct bch_dev *ca = bch2_dev_rcu(c, lp.ptr.dev);
+ struct bch_dev *ca = bch2_dev_rcu_noerror(c, lp.ptr.dev);
bool same_bucket = ca && PTR_BUCKET_NR(ca, &lp.ptr) == PTR_BUCKET_NR(ca, &rp.ptr);
if (!same_bucket)
@@ -815,14 +815,14 @@ static inline unsigned __extent_ptr_durability(struct bch_dev *ca, struct extent
unsigned bch2_extent_ptr_desired_durability(struct bch_fs *c, struct extent_ptr_decoded *p)
{
- struct bch_dev *ca = bch2_dev_rcu(c, p->ptr.dev);
+ struct bch_dev *ca = bch2_dev_rcu_noerror(c, p->ptr.dev);
return ca ? __extent_ptr_durability(ca, p) : 0;
}
unsigned bch2_extent_ptr_durability(struct bch_fs *c, struct extent_ptr_decoded *p)
{
- struct bch_dev *ca = bch2_dev_rcu(c, p->ptr.dev);
+ struct bch_dev *ca = bch2_dev_rcu_noerror(c, p->ptr.dev);
if (!ca || ca->mi.state == BCH_MEMBER_STATE_failed)
return 0;
@@ -995,6 +995,22 @@ void bch2_bkey_drop_device_noerror(struct bkey_s k, unsigned dev)
bch2_bkey_drop_ptrs_noerror(k, ptr, ptr->dev == dev);
}
+void bch2_bkey_drop_ec(struct bkey_i *k, unsigned dev)
+{
+ struct bkey_ptrs ptrs = bch2_bkey_ptrs(bkey_i_to_s(k));
+ union bch_extent_entry *entry, *ec = NULL;
+
+ bkey_extent_entry_for_each(ptrs, entry) {
+ if (extent_entry_type(entry) == BCH_EXTENT_ENTRY_stripe_ptr)
+ ec = entry;
+ else if (extent_entry_type(entry) == BCH_EXTENT_ENTRY_ptr &&
+ entry->ptr.dev == dev) {
+ bch2_bkey_extent_entry_drop(k, ec);
+ return;
+ }
+ }
+}
+
const struct bch_extent_ptr *bch2_bkey_has_device_c(struct bkey_s_c k, unsigned dev)
{
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
@@ -1028,7 +1044,7 @@ bool bch2_bkey_has_target(struct bch_fs *c, struct bkey_s_c k, unsigned target)
guard(rcu)();
bkey_for_each_ptr(ptrs, ptr)
if (bch2_dev_in_target(c, ptr->dev, target) &&
- (ca = bch2_dev_rcu(c, ptr->dev)) &&
+ (ca = bch2_dev_rcu_noerror(c, ptr->dev)) &&
(!ptr->cached ||
!dev_ptr_stale_rcu(ca, ptr)))
return true;
@@ -1212,7 +1228,7 @@ bool bch2_extent_normalize(struct bch_fs *c, struct bkey_s k)
guard(rcu)();
bch2_bkey_drop_ptrs(k, ptr,
ptr->cached &&
- (!(ca = bch2_dev_rcu(c, ptr->dev)) ||
+ (!(ca = bch2_dev_rcu_noerror(c, ptr->dev)) ||
dev_ptr_stale_rcu(ca, ptr) > 0));
return bkey_deleted(k.k);
@@ -1757,3 +1773,4 @@ int bch2_cut_back_s(struct bpos where, struct bkey_s k)
memset(bkey_val_end(k), 0, val_u64s_delta * sizeof(u64));
return -val_u64s_delta;
}
+