~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/bcachefs/buckets.h

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /fs/bcachefs/buckets.h (Version linux-6.12-rc7) and /fs/bcachefs/buckets.h (Version linux-2.6.0)


  1 /* SPDX-License-Identifier: GPL-2.0 */              1 
  2 /*                                                
  3  * Code for manipulating bucket marks for garb    
  4  *                                                
  5  * Copyright 2014 Datera, Inc.                    
  6  */                                               
  7                                                   
  8 #ifndef _BUCKETS_H                                
  9 #define _BUCKETS_H                                
 10                                                   
 11 #include "buckets_types.h"                        
 12 #include "extents.h"                              
 13 #include "sb-members.h"                           
 14                                                   
 15 static inline u64 sector_to_bucket(const struc    
 16 {                                                 
 17         return div_u64(s, ca->mi.bucket_size);    
 18 }                                                 
 19                                                   
 20 static inline sector_t bucket_to_sector(const     
 21 {                                                 
 22         return ((sector_t) b) * ca->mi.bucket_    
 23 }                                                 
 24                                                   
 25 static inline sector_t bucket_remainder(const     
 26 {                                                 
 27         u32 remainder;                            
 28                                                   
 29         div_u64_rem(s, ca->mi.bucket_size, &re    
 30         return remainder;                         
 31 }                                                 
 32                                                   
 33 static inline u64 sector_to_bucket_and_offset(    
 34 {                                                 
 35         return div_u64_rem(s, ca->mi.bucket_si    
 36 }                                                 
 37                                                   
 38 #define for_each_bucket(_b, _buckets)             
 39         for (_b = (_buckets)->b + (_buckets)->    
 40              _b < (_buckets)->b + (_buckets)->    
 41                                                   
 42 /*                                                
 43  * Ugly hack alert:                               
 44  *                                                
 45  * We need to cram a spinlock in a single byte    
 46  * in struct bucket, and we care about the siz    
 47  * in memory state for every single bucket on     
 48  *                                                
 49  * We used to do                                  
 50  *   while (xchg(&b->lock, 1) cpu_relax();        
 51  * but, it turns out not all architectures sup    
 52  *                                                
 53  * So now we use bit_spin_lock(), with fun gam    
 54  * ulong for this - we just need to make sure     
 55  * first byte.                                    
 56  */                                               
 57                                                   
 58 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__     
 59 #define BUCKET_LOCK_BITNR       0                 
 60 #else                                             
 61 #define BUCKET_LOCK_BITNR       (BITS_PER_LONG    
 62 #endif                                            
 63                                                   
 64 union ulong_byte_assert {                         
 65         ulong   ulong;                            
 66         u8      byte;                             
 67 };                                                
 68                                                   
 69 static inline void bucket_unlock(struct bucket    
 70 {                                                 
 71         BUILD_BUG_ON(!((union ulong_byte_asser    
 72                                                   
 73         clear_bit_unlock(BUCKET_LOCK_BITNR, (v    
 74         wake_up_bit((void *) &b->lock, BUCKET_    
 75 }                                                 
 76                                                   
 77 static inline void bucket_lock(struct bucket *    
 78 {                                                 
 79         wait_on_bit_lock((void *) &b->lock, BU    
 80                          TASK_UNINTERRUPTIBLE)    
 81 }                                                 
 82                                                   
 83 static inline struct bucket *gc_bucket(struct     
 84 {                                                 
 85         return genradix_ptr(&ca->buckets_gc, b    
 86 }                                                 
 87                                                   
 88 static inline struct bucket_gens *bucket_gens(    
 89 {                                                 
 90         return rcu_dereference_check(ca->bucke    
 91                                      !ca->fs |    
 92                                      percpu_rw    
 93                                      lockdep_i    
 94                                      lockdep_i    
 95 }                                                 
 96                                                   
 97 static inline u8 *bucket_gen(struct bch_dev *c    
 98 {                                                 
 99         struct bucket_gens *gens = bucket_gens    
100                                                   
101         if (b - gens->first_bucket >= gens->nb    
102                 return NULL;                      
103         return gens->b + b;                       
104 }                                                 
105                                                   
106 static inline int bucket_gen_get_rcu(struct bc    
107 {                                                 
108         u8 *gen = bucket_gen(ca, b);              
109         return gen ? *gen : -1;                   
110 }                                                 
111                                                   
112 static inline int bucket_gen_get(struct bch_de    
113 {                                                 
114         rcu_read_lock();                          
115         int ret = bucket_gen_get_rcu(ca, b);      
116         rcu_read_unlock();                        
117         return ret;                               
118 }                                                 
119                                                   
120 static inline size_t PTR_BUCKET_NR(const struc    
121                                    const struc    
122 {                                                 
123         return sector_to_bucket(ca, ptr->offse    
124 }                                                 
125                                                   
126 static inline struct bpos PTR_BUCKET_POS(const    
127                                          const    
128 {                                                 
129         return POS(ptr->dev, PTR_BUCKET_NR(ca,    
130 }                                                 
131                                                   
132 static inline struct bpos PTR_BUCKET_POS_OFFSE    
133                                                   
134                                                   
135 {                                                 
136         return POS(ptr->dev, sector_to_bucket_    
137 }                                                 
138                                                   
139 static inline struct bucket *PTR_GC_BUCKET(str    
140                                            con    
141 {                                                 
142         return gc_bucket(ca, PTR_BUCKET_NR(ca,    
143 }                                                 
144                                                   
145 static inline enum bch_data_type ptr_data_type    
146                                                   
147 {                                                 
148         if (bkey_is_btree_ptr(k))                 
149                 return BCH_DATA_btree;            
150                                                   
151         return ptr->cached ? BCH_DATA_cached :    
152 }                                                 
153                                                   
154 static inline s64 ptr_disk_sectors(s64 sectors    
155 {                                                 
156         EBUG_ON(sectors < 0);                     
157                                                   
158         return crc_is_compressed(p.crc)           
159                 ? DIV_ROUND_UP_ULL(sectors * p    
160                                    p.crc.uncom    
161                 : sectors;                        
162 }                                                 
163                                                   
164 static inline int gen_cmp(u8 a, u8 b)             
165 {                                                 
166         return (s8) (a - b);                      
167 }                                                 
168                                                   
169 static inline int gen_after(u8 a, u8 b)           
170 {                                                 
171         int r = gen_cmp(a, b);                    
172                                                   
173         return r > 0 ? r : 0;                     
174 }                                                 
175                                                   
176 static inline int dev_ptr_stale_rcu(struct bch    
177 {                                                 
178         int gen = bucket_gen_get_rcu(ca, PTR_B    
179         return gen < 0 ? gen : gen_after(gen,     
180 }                                                 
181                                                   
182 /**                                               
183  * dev_ptr_stale() - check if a pointer points    
184  * invalidated.                                   
185  */                                               
186 static inline int dev_ptr_stale(struct bch_dev    
187 {                                                 
188         rcu_read_lock();                          
189         int ret = dev_ptr_stale_rcu(ca, ptr);     
190         rcu_read_unlock();                        
191         return ret;                               
192 }                                                 
193                                                   
194 /* Device usage: */                               
195                                                   
196 void bch2_dev_usage_read_fast(struct bch_dev *    
197 static inline struct bch_dev_usage bch2_dev_us    
198 {                                                 
199         struct bch_dev_usage ret;                 
200                                                   
201         bch2_dev_usage_read_fast(ca, &ret);       
202         return ret;                               
203 }                                                 
204                                                   
205 void bch2_dev_usage_to_text(struct printbuf *,    
206                                                   
207 static inline u64 bch2_dev_buckets_reserved(st    
208 {                                                 
209         s64 reserved = 0;                         
210                                                   
211         switch (watermark) {                      
212         case BCH_WATERMARK_NR:                    
213                 BUG();                            
214         case BCH_WATERMARK_stripe:                
215                 reserved += ca->mi.nbuckets >>    
216                 fallthrough;                      
217         case BCH_WATERMARK_normal:                
218                 reserved += ca->mi.nbuckets >>    
219                 fallthrough;                      
220         case BCH_WATERMARK_copygc:                
221                 reserved += ca->nr_btree_reser    
222                 fallthrough;                      
223         case BCH_WATERMARK_btree:                 
224                 reserved += ca->nr_btree_reser    
225                 fallthrough;                      
226         case BCH_WATERMARK_btree_copygc:          
227         case BCH_WATERMARK_reclaim:               
228         case BCH_WATERMARK_interior_updates:      
229                 break;                            
230         }                                         
231                                                   
232         return reserved;                          
233 }                                                 
234                                                   
235 static inline u64 dev_buckets_free(struct bch_    
236                                    struct bch_    
237                                    enum bch_wa    
238 {                                                 
239         return max_t(s64, 0,                      
240                      usage.d[BCH_DATA_free].bu    
241                      ca->nr_open_buckets -        
242                      bch2_dev_buckets_reserved    
243 }                                                 
244                                                   
245 static inline u64 __dev_buckets_available(stru    
246                                           stru    
247                                           enum    
248 {                                                 
249         return max_t(s64, 0,                      
250                        usage.d[BCH_DATA_free].    
251                      + usage.d[BCH_DATA_cached    
252                      + usage.d[BCH_DATA_need_g    
253                      + usage.d[BCH_DATA_need_d    
254                      - ca->nr_open_buckets        
255                      - bch2_dev_buckets_reserv    
256 }                                                 
257                                                   
258 static inline u64 dev_buckets_available(struct    
259                                         enum b    
260 {                                                 
261         return __dev_buckets_available(ca, bch    
262 }                                                 
263                                                   
264 /* Filesystem usage: */                           
265                                                   
266 static inline unsigned dev_usage_u64s(void)       
267 {                                                 
268         return sizeof(struct bch_dev_usage) /     
269 }                                                 
270                                                   
271 struct bch_fs_usage_short                         
272 bch2_fs_usage_read_short(struct bch_fs *);        
273                                                   
274 int bch2_bucket_ref_update(struct btree_trans     
275                            struct bkey_s_c, co    
276                            s64, enum bch_data_    
277                                                   
278 int bch2_check_fix_ptrs(struct btree_trans *,     
279                         enum btree_id, unsigne    
280                         enum btree_iter_update    
281                                                   
282 int bch2_trigger_extent(struct btree_trans *,     
283                         struct bkey_s_c, struc    
284                         enum btree_iter_update    
285 int bch2_trigger_reservation(struct btree_tran    
286                           struct bkey_s_c, str    
287                           enum btree_iter_upda    
288                                                   
289 #define trigger_run_overwrite_then_insert(_fn,    
290 ({                                                
291         int ret = 0;                              
292                                                   
293         if (_old.k->type)                         
294                 ret = _fn(_trans, _btree_id, _    
295         if (!ret && _new.k->type)                 
296                 ret = _fn(_trans, _btree_id, _    
297         ret;                                      
298 })                                                
299                                                   
300 void bch2_trans_account_disk_usage_change(stru    
301                                                   
302 int bch2_trans_mark_metadata_bucket(struct btr    
303                                     enum bch_d    
304                                     enum btree    
305 int bch2_trans_mark_dev_sb(struct bch_fs *, st    
306                                     enum btree    
307 int bch2_trans_mark_dev_sbs_flags(struct bch_f    
308                                     enum btree    
309 int bch2_trans_mark_dev_sbs(struct bch_fs *);     
310                                                   
311 static inline bool is_superblock_bucket(struct    
312 {                                                 
313         struct bch_sb_layout *layout = &ca->di    
314         u64 b_offset    = bucket_to_sector(ca,    
315         u64 b_end       = bucket_to_sector(ca,    
316         unsigned i;                               
317                                                   
318         if (!b)                                   
319                 return true;                      
320                                                   
321         for (i = 0; i < layout->nr_superblocks    
322                 u64 offset = le64_to_cpu(layou    
323                 u64 end = offset + (1 << layou    
324                                                   
325                 if (!(offset >= b_end || end <    
326                         return true;              
327         }                                         
328                                                   
329         return false;                             
330 }                                                 
331                                                   
332 static inline const char *bch2_data_type_str(e    
333 {                                                 
334         return type < BCH_DATA_NR                 
335                 ? __bch2_data_types[type]         
336                 : "(invalid data type)";          
337 }                                                 
338                                                   
339 /* disk reservations: */                          
340                                                   
341 static inline void bch2_disk_reservation_put(s    
342                                              s    
343 {                                                 
344         if (res->sectors) {                       
345                 this_cpu_sub(*c->online_reserv    
346                 res->sectors = 0;                 
347         }                                         
348 }                                                 
349                                                   
350 enum bch_reservation_flags {                      
351         BCH_DISK_RESERVATION_NOFAIL     = 1 <<    
352         BCH_DISK_RESERVATION_PARTIAL    = 1 <<    
353 };                                                
354                                                   
355 int __bch2_disk_reservation_add(struct bch_fs     
356                                 u64, enum bch_    
357                                                   
358 static inline int bch2_disk_reservation_add(st    
359                                             u6    
360 {                                                 
361 #ifdef __KERNEL__                                 
362         u64 old, new;                             
363                                                   
364         old = this_cpu_read(c->pcpu->sectors_a    
365         do {                                      
366                 if (sectors > old)                
367                         return __bch2_disk_res    
368                                                   
369                 new = old - sectors;              
370         } while (!this_cpu_try_cmpxchg(c->pcpu    
371                                                   
372         this_cpu_add(*c->online_reserved, sect    
373         res->sectors                    += sec    
374         return 0;                                 
375 #else                                             
376         return __bch2_disk_reservation_add(c,     
377 #endif                                            
378 }                                                 
379                                                   
380 static inline struct disk_reservation             
381 bch2_disk_reservation_init(struct bch_fs *c, u    
382 {                                                 
383         return (struct disk_reservation) {        
384                 .sectors        = 0,              
385 #if 0                                             
386                 /* not used yet: */               
387                 .gen            = c->capacity_    
388 #endif                                            
389                 .nr_replicas    = nr_replicas,    
390         };                                        
391 }                                                 
392                                                   
393 static inline int bch2_disk_reservation_get(st    
394                                             st    
395                                             u6    
396                                             in    
397 {                                                 
398         *res = bch2_disk_reservation_init(c, n    
399                                                   
400         return bch2_disk_reservation_add(c, re    
401 }                                                 
402                                                   
403 #define RESERVE_FACTOR  6                         
404                                                   
405 static inline u64 avail_factor(u64 r)             
406 {                                                 
407         return div_u64(r << RESERVE_FACTOR, (1    
408 }                                                 
409                                                   
410 void bch2_buckets_nouse_free(struct bch_fs *);    
411 int bch2_buckets_nouse_alloc(struct bch_fs *);    
412                                                   
413 int bch2_dev_buckets_resize(struct bch_fs *, s    
414 void bch2_dev_buckets_free(struct bch_dev *);     
415 int bch2_dev_buckets_alloc(struct bch_fs *, st    
416                                                   
417 #endif /* _BUCKETS_H */                           
418                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php