X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libbcachefs%2Fsuper.h;h=d4e939c808faf5adb95a4edf24da4b271880b0d2;hb=b0c9ad15f4e5cee60973a8f5f6dc49acfeec9755;hp=4598de9b9c5e001a6fcc4f2a2150d15871b9d288;hpb=b485aae1bac95e3b5be235116e2bc43da85906c5;p=bcachefs-tools-debian diff --git a/libbcachefs/super.h b/libbcachefs/super.h index 4598de9..d4e939c 100644 --- a/libbcachefs/super.h +++ b/libbcachefs/super.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _BCACHEFS_SUPER_H #define _BCACHEFS_SUPER_H @@ -25,6 +26,12 @@ static inline sector_t bucket_remainder(const struct bch_dev *ca, sector_t s) return remainder; } +static inline size_t sector_to_bucket_and_offset(const struct bch_dev *ca, sector_t s, + u32 *offset) +{ + return div_u64_rem(s, ca->mi.bucket_size, offset); +} + static inline bool bch2_dev_is_online(struct bch_dev *ca) { return !percpu_ref_is_zero(&ca->io_ref); @@ -33,7 +40,7 @@ static inline bool bch2_dev_is_online(struct bch_dev *ca) static inline bool bch2_dev_is_readable(struct bch_dev *ca) { return bch2_dev_is_online(ca) && - ca->mi.state != BCH_MEMBER_STATE_FAILED; + ca->mi.state != BCH_MEMBER_STATE_failed; } static inline bool bch2_dev_get_ioref(struct bch_dev *ca, int rw) @@ -41,8 +48,8 @@ static inline bool bch2_dev_get_ioref(struct bch_dev *ca, int rw) if (!percpu_ref_tryget(&ca->io_ref)) return false; - if (ca->mi.state == BCH_MEMBER_STATE_RW || - (ca->mi.state == BCH_MEMBER_STATE_RO && rw == READ)) + if (ca->mi.state == BCH_MEMBER_STATE_rw || + (ca->mi.state == BCH_MEMBER_STATE_ro && rw == READ)) return true; percpu_ref_put(&ca->io_ref); @@ -81,9 +88,10 @@ static inline void bch2_dev_list_drop_dev(struct bch_devs_list *devs, static inline void bch2_dev_list_add_dev(struct bch_devs_list *devs, unsigned dev) { - BUG_ON(bch2_dev_list_has_dev(*devs, dev)); - BUG_ON(devs->nr >= BCH_REPLICAS_MAX); - devs->devs[devs->nr++] = dev; + if (!bch2_dev_list_has_dev(*devs, dev)) { + BUG_ON(devs->nr >= ARRAY_SIZE(devs->devs)); + devs->devs[devs->nr++] = dev; + } } static inline struct bch_devs_list bch2_dev_list_single(unsigned dev) @@ -106,11 +114,8 @@ static inline struct bch_dev *__bch2_next_dev(struct bch_fs *c, unsigned *iter, return ca; } -#define __for_each_member_device(ca, c, iter, mask) \ - for ((iter) = 0; ((ca) = __bch2_next_dev((c), &(iter), mask)); (iter)++) - #define for_each_member_device_rcu(ca, c, iter, mask) \ - __for_each_member_device(ca, c, iter, mask) + for ((iter) = 0; ((ca) = __bch2_next_dev((c), &(iter), mask)); (iter)++) static inline struct bch_dev *bch2_get_next_dev(struct bch_fs *c, unsigned *iter) { @@ -157,11 +162,11 @@ static inline struct bch_dev *bch2_get_next_online_dev(struct bch_fs *c, __for_each_online_member(ca, c, iter, ~0) #define for_each_rw_member(ca, c, iter) \ - __for_each_online_member(ca, c, iter, 1 << BCH_MEMBER_STATE_RW) + __for_each_online_member(ca, c, iter, 1 << BCH_MEMBER_STATE_rw) #define for_each_readable_member(ca, c, iter) \ __for_each_online_member(ca, c, iter, \ - (1 << BCH_MEMBER_STATE_RW)|(1 << BCH_MEMBER_STATE_RO)) + (1 << BCH_MEMBER_STATE_rw)|(1 << BCH_MEMBER_STATE_ro)) /* * If a key exists that references a device, the device won't be going away and @@ -196,9 +201,29 @@ static inline struct bch_devs_mask bch2_online_devs(struct bch_fs *c) return devs; } -struct bch_fs *bch2_bdev_to_fs(struct block_device *); +static inline bool is_superblock_bucket(struct bch_dev *ca, u64 b) +{ + struct bch_sb_layout *layout = &ca->disk_sb.sb->layout; + u64 b_offset = bucket_to_sector(ca, b); + u64 b_end = bucket_to_sector(ca, b + 1); + unsigned i; + + if (!b) + return true; + + for (i = 0; i < layout->nr_superblocks; i++) { + u64 offset = le64_to_cpu(layout->sb_offset[i]); + u64 end = offset + (1 << layout->sb_max_size_bits); + + if (!(offset >= b_end || end <= b_offset)) + return true; + } + + return false; +} + +struct bch_fs *bch2_dev_to_fs(dev_t); struct bch_fs *bch2_uuid_to_fs(uuid_le); -int bch2_congested(void *, int); bool bch2_dev_state_allowed(struct bch_fs *, struct bch_dev *, enum bch_member_state, int); @@ -218,14 +243,24 @@ struct bch_dev *bch2_dev_lookup(struct bch_fs *, const char *); bool bch2_fs_emergency_read_only(struct bch_fs *); void bch2_fs_read_only(struct bch_fs *); -int __bch2_fs_read_write(struct bch_fs *, bool); int bch2_fs_read_write(struct bch_fs *); int bch2_fs_read_write_early(struct bch_fs *); +/* + * Only for use in the recovery/fsck path: + */ +static inline void bch2_fs_lazy_rw(struct bch_fs *c) +{ + if (!test_bit(BCH_FS_RW, &c->flags) && + !test_bit(BCH_FS_WAS_RW, &c->flags)) + bch2_fs_read_write_early(c); +} + +void __bch2_fs_stop(struct bch_fs *); +void bch2_fs_free(struct bch_fs *); void bch2_fs_stop(struct bch_fs *); int bch2_fs_start(struct bch_fs *); struct bch_fs *bch2_fs_open(char * const *, unsigned, struct bch_opts); -const char *bch2_fs_open_incremental(const char *path); #endif /* _BCACHEFS_SUPER_H */