diff options
Diffstat (limited to 'fs/bcachefs/backpointers.h')
| -rw-r--r-- | fs/bcachefs/backpointers.h | 43 | 
1 files changed, 29 insertions, 14 deletions
diff --git a/fs/bcachefs/backpointers.h b/fs/bcachefs/backpointers.h index c1b274eadda1..6021de1c5e98 100644 --- a/fs/bcachefs/backpointers.h +++ b/fs/bcachefs/backpointers.h @@ -6,6 +6,7 @@  #include "btree_iter.h"  #include "btree_update.h"  #include "buckets.h" +#include "error.h"  #include "super.h"  static inline u64 swab40(u64 x) @@ -18,7 +19,7 @@ static inline u64 swab40(u64 x)  }  int bch2_backpointer_invalid(struct bch_fs *, struct bkey_s_c k, -			     enum bkey_invalid_flags, struct printbuf *); +			     enum bch_validate_flags, struct printbuf *);  void bch2_backpointer_to_text(struct printbuf *, const struct bch_backpointer *);  void bch2_backpointer_k_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);  void bch2_backpointer_swab(struct bkey_s); @@ -36,15 +37,29 @@ void bch2_backpointer_swab(struct bkey_s);   * Convert from pos in backpointer btree to pos of corresponding bucket in alloc   * btree:   */ -static inline struct bpos bp_pos_to_bucket(const struct bch_fs *c, -					   struct bpos bp_pos) +static inline struct bpos bp_pos_to_bucket(const struct bch_dev *ca, struct bpos bp_pos)  { -	struct bch_dev *ca = bch_dev_bkey_exists(c, bp_pos.inode);  	u64 bucket_sector = bp_pos.offset >> MAX_EXTENT_COMPRESS_RATIO_SHIFT;  	return POS(bp_pos.inode, sector_to_bucket(ca, bucket_sector));  } +static inline bool bp_pos_to_bucket_nodev_noerror(struct bch_fs *c, struct bpos bp_pos, struct bpos *bucket) +{ +	rcu_read_lock(); +	struct bch_dev *ca = bch2_dev_rcu(c, bp_pos.inode); +	if (ca) +		*bucket = bp_pos_to_bucket(ca, bp_pos); +	rcu_read_unlock(); +	return ca != NULL; +} + +static inline bool bp_pos_to_bucket_nodev(struct bch_fs *c, struct bpos bp_pos, struct bpos *bucket) +{ +	return !bch2_fs_inconsistent_on(!bp_pos_to_bucket_nodev_noerror(c, bp_pos, bucket), +					c, "backpointer for missing device %llu", bp_pos.inode); +} +  static inline struct bpos bucket_pos_to_bp_noerror(const struct bch_dev *ca,  						   struct bpos bucket,  						   u64 bucket_offset) @@ -57,32 +72,32 @@ static inline struct bpos bucket_pos_to_bp_noerror(const struct bch_dev *ca,  /*   * Convert from pos in alloc btree + bucket offset to pos in backpointer btree:   */ -static inline struct bpos bucket_pos_to_bp(const struct bch_fs *c, +static inline struct bpos bucket_pos_to_bp(const struct bch_dev *ca,  					   struct bpos bucket,  					   u64 bucket_offset)  { -	struct bch_dev *ca = bch_dev_bkey_exists(c, bucket.inode);  	struct bpos ret = bucket_pos_to_bp_noerror(ca, bucket, bucket_offset); -	EBUG_ON(!bkey_eq(bucket, bp_pos_to_bucket(c, ret))); +	EBUG_ON(!bkey_eq(bucket, bp_pos_to_bucket(ca, ret)));  	return ret;  } -int bch2_bucket_backpointer_mod_nowritebuffer(struct btree_trans *, struct bpos bucket, -				struct bch_backpointer, struct bkey_s_c, bool); +int bch2_bucket_backpointer_mod_nowritebuffer(struct btree_trans *, struct bch_dev *, +				struct bpos bucket, struct bch_backpointer, struct bkey_s_c, bool);  static inline int bch2_bucket_backpointer_mod(struct btree_trans *trans, +				struct bch_dev *ca,  				struct bpos bucket,  				struct bch_backpointer bp,  				struct bkey_s_c orig_k,  				bool insert)  {  	if (unlikely(bch2_backpointers_no_use_write_buffer)) -		return bch2_bucket_backpointer_mod_nowritebuffer(trans, bucket, bp, orig_k, insert); +		return bch2_bucket_backpointer_mod_nowritebuffer(trans, ca, bucket, bp, orig_k, insert);  	struct bkey_i_backpointer bp_k;  	bkey_backpointer_init(&bp_k.k_i); -	bp_k.k.p = bucket_pos_to_bp(trans->c, bucket, bp.bucket_offset); +	bp_k.k.p = bucket_pos_to_bp(ca, bucket, bp.bucket_offset);  	bp_k.v = bp;  	if (!insert) { @@ -120,7 +135,7 @@ static inline enum bch_data_type bch2_bkey_ptr_data_type(struct bkey_s_c k,  	}  } -static inline void bch2_extent_ptr_to_bp(struct bch_fs *c, +static inline void bch2_extent_ptr_to_bp(struct bch_fs *c, struct bch_dev *ca,  			   enum btree_id btree_id, unsigned level,  			   struct bkey_s_c k, struct extent_ptr_decoded p,  			   const union bch_extent_entry *entry, @@ -130,7 +145,7 @@ static inline void bch2_extent_ptr_to_bp(struct bch_fs *c,  	s64 sectors = level ? btree_sectors(c) : k.k->size;  	u32 bucket_offset; -	*bucket_pos = PTR_BUCKET_POS_OFFSET(c, &p.ptr, &bucket_offset); +	*bucket_pos = PTR_BUCKET_POS_OFFSET(ca, &p.ptr, &bucket_offset);  	*bp = (struct bch_backpointer) {  		.btree_id	= btree_id,  		.level		= level, @@ -142,7 +157,7 @@ static inline void bch2_extent_ptr_to_bp(struct bch_fs *c,  	};  } -int bch2_get_next_backpointer(struct btree_trans *, struct bpos, int, +int bch2_get_next_backpointer(struct btree_trans *, struct bch_dev *ca, struct bpos, int,  			      struct bpos *, struct bch_backpointer *, unsigned);  struct bkey_s_c bch2_backpointer_get_key(struct btree_trans *, struct btree_iter *,  					 struct bpos, struct bch_backpointer,  |