0001
0002
0003 #ifndef BTRFS_SUBPAGE_H
0004 #define BTRFS_SUBPAGE_H
0005
0006 #include <linux/spinlock.h>
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 struct btrfs_subpage_info {
0024
0025 unsigned int bitmap_nr_bits;
0026
0027
0028 unsigned int total_nr_bits;
0029
0030
0031
0032
0033
0034 unsigned int uptodate_offset;
0035 unsigned int error_offset;
0036 unsigned int dirty_offset;
0037 unsigned int writeback_offset;
0038 unsigned int ordered_offset;
0039 unsigned int checked_offset;
0040 };
0041
0042
0043
0044
0045
0046 struct btrfs_subpage {
0047
0048 spinlock_t lock;
0049
0050
0051
0052
0053
0054
0055
0056 atomic_t readers;
0057 union {
0058
0059
0060
0061
0062
0063
0064 atomic_t eb_refs;
0065
0066
0067 atomic_t writers;
0068 };
0069 unsigned long bitmaps[];
0070 };
0071
0072 enum btrfs_subpage_type {
0073 BTRFS_SUBPAGE_METADATA,
0074 BTRFS_SUBPAGE_DATA,
0075 };
0076
0077 bool btrfs_is_subpage(const struct btrfs_fs_info *fs_info, struct page *page);
0078
0079 void btrfs_init_subpage_info(struct btrfs_subpage_info *subpage_info, u32 sectorsize);
0080 int btrfs_attach_subpage(const struct btrfs_fs_info *fs_info,
0081 struct page *page, enum btrfs_subpage_type type);
0082 void btrfs_detach_subpage(const struct btrfs_fs_info *fs_info,
0083 struct page *page);
0084
0085
0086 struct btrfs_subpage *btrfs_alloc_subpage(const struct btrfs_fs_info *fs_info,
0087 enum btrfs_subpage_type type);
0088 void btrfs_free_subpage(struct btrfs_subpage *subpage);
0089
0090 void btrfs_page_inc_eb_refs(const struct btrfs_fs_info *fs_info,
0091 struct page *page);
0092 void btrfs_page_dec_eb_refs(const struct btrfs_fs_info *fs_info,
0093 struct page *page);
0094
0095 void btrfs_subpage_start_reader(const struct btrfs_fs_info *fs_info,
0096 struct page *page, u64 start, u32 len);
0097 void btrfs_subpage_end_reader(const struct btrfs_fs_info *fs_info,
0098 struct page *page, u64 start, u32 len);
0099
0100 void btrfs_subpage_start_writer(const struct btrfs_fs_info *fs_info,
0101 struct page *page, u64 start, u32 len);
0102 bool btrfs_subpage_end_and_test_writer(const struct btrfs_fs_info *fs_info,
0103 struct page *page, u64 start, u32 len);
0104 int btrfs_page_start_writer_lock(const struct btrfs_fs_info *fs_info,
0105 struct page *page, u64 start, u32 len);
0106 void btrfs_page_end_writer_lock(const struct btrfs_fs_info *fs_info,
0107 struct page *page, u64 start, u32 len);
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123 #define DECLARE_BTRFS_SUBPAGE_OPS(name) \
0124 void btrfs_subpage_set_##name(const struct btrfs_fs_info *fs_info, \
0125 struct page *page, u64 start, u32 len); \
0126 void btrfs_subpage_clear_##name(const struct btrfs_fs_info *fs_info, \
0127 struct page *page, u64 start, u32 len); \
0128 bool btrfs_subpage_test_##name(const struct btrfs_fs_info *fs_info, \
0129 struct page *page, u64 start, u32 len); \
0130 void btrfs_page_set_##name(const struct btrfs_fs_info *fs_info, \
0131 struct page *page, u64 start, u32 len); \
0132 void btrfs_page_clear_##name(const struct btrfs_fs_info *fs_info, \
0133 struct page *page, u64 start, u32 len); \
0134 bool btrfs_page_test_##name(const struct btrfs_fs_info *fs_info, \
0135 struct page *page, u64 start, u32 len); \
0136 void btrfs_page_clamp_set_##name(const struct btrfs_fs_info *fs_info, \
0137 struct page *page, u64 start, u32 len); \
0138 void btrfs_page_clamp_clear_##name(const struct btrfs_fs_info *fs_info, \
0139 struct page *page, u64 start, u32 len); \
0140 bool btrfs_page_clamp_test_##name(const struct btrfs_fs_info *fs_info, \
0141 struct page *page, u64 start, u32 len);
0142
0143 DECLARE_BTRFS_SUBPAGE_OPS(uptodate);
0144 DECLARE_BTRFS_SUBPAGE_OPS(error);
0145 DECLARE_BTRFS_SUBPAGE_OPS(dirty);
0146 DECLARE_BTRFS_SUBPAGE_OPS(writeback);
0147 DECLARE_BTRFS_SUBPAGE_OPS(ordered);
0148 DECLARE_BTRFS_SUBPAGE_OPS(checked);
0149
0150 bool btrfs_subpage_clear_and_test_dirty(const struct btrfs_fs_info *fs_info,
0151 struct page *page, u64 start, u32 len);
0152
0153 void btrfs_page_assert_not_dirty(const struct btrfs_fs_info *fs_info,
0154 struct page *page);
0155 void btrfs_page_unlock_writer(struct btrfs_fs_info *fs_info, struct page *page,
0156 u64 start, u32 len);
0157
0158 #endif