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

TOMOYO Linux Cross Reference
Linux/fs/bcachefs/btree_update.c

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/btree_update.c (Version linux-6.12-rc7) and /fs/bcachefs/btree_update.c (Version linux-5.15.171)


  1 // SPDX-License-Identifier: GPL-2.0                 1 
  2                                                   
  3 #include "bcachefs.h"                             
  4 #include "btree_update.h"                         
  5 #include "btree_iter.h"                           
  6 #include "btree_journal_iter.h"                   
  7 #include "btree_locking.h"                        
  8 #include "buckets.h"                              
  9 #include "debug.h"                                
 10 #include "errcode.h"                              
 11 #include "error.h"                                
 12 #include "extents.h"                              
 13 #include "keylist.h"                              
 14 #include "snapshot.h"                             
 15 #include "trace.h"                                
 16                                                   
 17 static inline int btree_insert_entry_cmp(const    
 18                                          const    
 19 {                                                 
 20         return   cmp_int(l->btree_id,   r->btr    
 21                  cmp_int(l->cached,     r->cac    
 22                  -cmp_int(l->level,     r->lev    
 23                  bpos_cmp(l->k->k.p,    r->k->    
 24 }                                                 
 25                                                   
 26 static int __must_check                           
 27 bch2_trans_update_by_path(struct btree_trans *    
 28                           struct bkey_i *, enu    
 29                           unsigned long ip);      
 30                                                   
 31 static noinline int extent_front_merge(struct     
 32                                        struct     
 33                                        struct     
 34                                        struct     
 35                                        enum bt    
 36 {                                                 
 37         struct bch_fs *c = trans->c;              
 38         struct bkey_i *update;                    
 39         int ret;                                  
 40                                                   
 41         if (unlikely(trans->journal_replay_not    
 42                 return 0;                         
 43                                                   
 44         update = bch2_bkey_make_mut_noupdate(t    
 45         ret = PTR_ERR_OR_ZERO(update);            
 46         if (ret)                                  
 47                 return ret;                       
 48                                                   
 49         if (!bch2_bkey_merge(c, bkey_i_to_s(up    
 50                 return 0;                         
 51                                                   
 52         ret =   bch2_key_has_snapshot_overwrit    
 53                 bch2_key_has_snapshot_overwrit    
 54         if (ret < 0)                              
 55                 return ret;                       
 56         if (ret)                                  
 57                 return 0;                         
 58                                                   
 59         ret = bch2_btree_delete_at(trans, iter    
 60         if (ret)                                  
 61                 return ret;                       
 62                                                   
 63         *insert = update;                         
 64         return 0;                                 
 65 }                                                 
 66                                                   
 67 static noinline int extent_back_merge(struct b    
 68                                       struct b    
 69                                       struct b    
 70                                       struct b    
 71 {                                                 
 72         struct bch_fs *c = trans->c;              
 73         int ret;                                  
 74                                                   
 75         if (unlikely(trans->journal_replay_not    
 76                 return 0;                         
 77                                                   
 78         ret =   bch2_key_has_snapshot_overwrit    
 79                 bch2_key_has_snapshot_overwrit    
 80         if (ret < 0)                              
 81                 return ret;                       
 82         if (ret)                                  
 83                 return 0;                         
 84                                                   
 85         bch2_bkey_merge(c, bkey_i_to_s(insert)    
 86         return 0;                                 
 87 }                                                 
 88                                                   
 89 /*                                                
 90  * When deleting, check if we need to emit a w    
 91  * something in an ancestor snapshot)             
 92  */                                               
 93 static int need_whiteout_for_snapshot(struct b    
 94                                       enum btr    
 95 {                                                 
 96         struct btree_iter iter;                   
 97         struct bkey_s_c k;                        
 98         u32 snapshot = pos.snapshot;              
 99         int ret;                                  
100                                                   
101         if (!bch2_snapshot_parent(trans->c, po    
102                 return 0;                         
103                                                   
104         pos.snapshot++;                           
105                                                   
106         for_each_btree_key_norestart(trans, it    
107                            BTREE_ITER_all_snap    
108                            BTREE_ITER_nopreser    
109                 if (!bkey_eq(k.k->p, pos))        
110                         break;                    
111                                                   
112                 if (bch2_snapshot_is_ancestor(    
113                                                   
114                         ret = !bkey_whiteout(k    
115                         break;                    
116                 }                                 
117         }                                         
118         bch2_trans_iter_exit(trans, &iter);       
119                                                   
120         return ret;                               
121 }                                                 
122                                                   
123 int __bch2_insert_snapshot_whiteouts(struct bt    
124                                    enum btree_    
125                                    struct bpos    
126                                    struct bpos    
127 {                                                 
128         struct bch_fs *c = trans->c;              
129         struct btree_iter old_iter, new_iter =    
130         struct bkey_s_c old_k, new_k;             
131         snapshot_id_list s;                       
132         struct bkey_i *update;                    
133         int ret = 0;                              
134                                                   
135         if (!bch2_snapshot_has_children(c, old    
136                 return 0;                         
137                                                   
138         darray_init(&s);                          
139                                                   
140         bch2_trans_iter_init(trans, &old_iter,    
141                              BTREE_ITER_not_ex    
142                              BTREE_ITER_all_sn    
143         while ((old_k = bch2_btree_iter_prev(&    
144                !(ret = bkey_err(old_k)) &&        
145                bkey_eq(old_pos, old_k.k->p)) {    
146                 struct bpos whiteout_pos =        
147                         SPOS(new_pos.inode, ne    
148                                                   
149                 if (!bch2_snapshot_is_ancestor    
150                     snapshot_list_has_ancestor    
151                         continue;                 
152                                                   
153                 new_k = bch2_bkey_get_iter(tra    
154                                            BTR    
155                                            BTR    
156                 ret = bkey_err(new_k);            
157                 if (ret)                          
158                         break;                    
159                                                   
160                 if (new_k.k->type == KEY_TYPE_    
161                         update = bch2_trans_km    
162                         ret = PTR_ERR_OR_ZERO(    
163                         if (ret)                  
164                                 break;            
165                                                   
166                         bkey_init(&update->k);    
167                         update->k.p               
168                         update->k.type            
169                                                   
170                         ret = bch2_trans_updat    
171                                                   
172                 }                                 
173                 bch2_trans_iter_exit(trans, &n    
174                                                   
175                 ret = snapshot_list_add(c, &s,    
176                 if (ret)                          
177                         break;                    
178         }                                         
179         bch2_trans_iter_exit(trans, &new_iter)    
180         bch2_trans_iter_exit(trans, &old_iter)    
181         darray_exit(&s);                          
182                                                   
183         return ret;                               
184 }                                                 
185                                                   
186 int bch2_trans_update_extent_overwrite(struct     
187                                        struct     
188                                        enum bt    
189                                        struct     
190                                        struct     
191 {                                                 
192         enum btree_id btree_id = iter->btree_i    
193         struct bkey_i *update;                    
194         struct bpos new_start = bkey_start_pos    
195         unsigned front_split = bkey_lt(bkey_st    
196         unsigned back_split  = bkey_gt(old.k->    
197         unsigned middle_split = (front_split |    
198                 old.k->p.snapshot != new.k->p.    
199         unsigned nr_splits = front_split + bac    
200         int ret = 0, compressed_sectors;          
201                                                   
202         /*                                        
203          * If we're going to be splitting a co    
204          * so that __bch2_trans_commit() can i    
205          * reservation:                           
206          */                                       
207         if (nr_splits > 1 &&                      
208             (compressed_sectors = bch2_bkey_se    
209                 trans->extra_disk_res += compr    
210                                                   
211         if (front_split) {                        
212                 update = bch2_bkey_make_mut_no    
213                 if ((ret = PTR_ERR_OR_ZERO(upd    
214                         return ret;               
215                                                   
216                 bch2_cut_back(new_start, updat    
217                                                   
218                 ret =   bch2_insert_snapshot_w    
219                                         old.k-    
220                         bch2_btree_insert_none    
221                                         BTREE_    
222                 if (ret)                          
223                         return ret;               
224         }                                         
225                                                   
226         /* If we're overwriting in a different    
227         if (middle_split) {                       
228                 update = bch2_bkey_make_mut_no    
229                 if ((ret = PTR_ERR_OR_ZERO(upd    
230                         return ret;               
231                                                   
232                 bch2_cut_front(new_start, upda    
233                 bch2_cut_back(new.k->p, update    
234                                                   
235                 ret =   bch2_insert_snapshot_w    
236                                         old.k-    
237                         bch2_btree_insert_none    
238                                           BTRE    
239                 if (ret)                          
240                         return ret;               
241         }                                         
242                                                   
243         if (bkey_le(old.k->p, new.k->p)) {        
244                 update = bch2_trans_kmalloc(tr    
245                 if ((ret = PTR_ERR_OR_ZERO(upd    
246                         return ret;               
247                                                   
248                 bkey_init(&update->k);            
249                 update->k.p = old.k->p;           
250                 update->k.p.snapshot = new.k->    
251                                                   
252                 if (new.k->p.snapshot != old.k    
253                         update->k.type = KEY_T    
254                 } else if (btree_type_has_snap    
255                         ret = need_whiteout_fo    
256                         if (ret < 0)              
257                                 return ret;       
258                         if (ret)                  
259                                 update->k.type    
260                 }                                 
261                                                   
262                 ret = bch2_btree_insert_nonext    
263                                           BTRE    
264                 if (ret)                          
265                         return ret;               
266         }                                         
267                                                   
268         if (back_split) {                         
269                 update = bch2_bkey_make_mut_no    
270                 if ((ret = PTR_ERR_OR_ZERO(upd    
271                         return ret;               
272                                                   
273                 bch2_cut_front(new.k->p, updat    
274                                                   
275                 ret = bch2_trans_update_by_pat    
276                                           BTRE    
277                                           flag    
278                 if (ret)                          
279                         return ret;               
280         }                                         
281                                                   
282         return 0;                                 
283 }                                                 
284                                                   
285 static int bch2_trans_update_extent(struct btr    
286                                     struct btr    
287                                     struct bke    
288                                     enum btree    
289 {                                                 
290         struct btree_iter iter;                   
291         struct bkey_s_c k;                        
292         enum btree_id btree_id = orig_iter->bt    
293         int ret = 0;                              
294                                                   
295         bch2_trans_iter_init(trans, &iter, btr    
296                              BTREE_ITER_intent    
297                              BTREE_ITER_with_u    
298                              BTREE_ITER_not_ex    
299         k = bch2_btree_iter_peek_upto(&iter, P    
300         if ((ret = bkey_err(k)))                  
301                 goto err;                         
302         if (!k.k)                                 
303                 goto out;                         
304                                                   
305         if (bkey_eq(k.k->p, bkey_start_pos(&in    
306                 if (bch2_bkey_maybe_mergable(k    
307                         ret = extent_front_mer    
308                         if (ret)                  
309                                 goto err;         
310                 }                                 
311                                                   
312                 goto next;                        
313         }                                         
314                                                   
315         while (bkey_gt(insert->k.p, bkey_start    
316                 bool done = bkey_lt(insert->k.    
317                                                   
318                 ret = bch2_trans_update_extent    
319                 if (ret)                          
320                         goto err;                 
321                                                   
322                 if (done)                         
323                         goto out;                 
324 next:                                             
325                 bch2_btree_iter_advance(&iter)    
326                 k = bch2_btree_iter_peek_upto(    
327                 if ((ret = bkey_err(k)))          
328                         goto err;                 
329                 if (!k.k)                         
330                         goto out;                 
331         }                                         
332                                                   
333         if (bch2_bkey_maybe_mergable(&insert->    
334                 ret = extent_back_merge(trans,    
335                 if (ret)                          
336                         goto err;                 
337         }                                         
338 out:                                              
339         if (!bkey_deleted(&insert->k))            
340                 ret = bch2_btree_insert_nonext    
341 err:                                              
342         bch2_trans_iter_exit(trans, &iter);       
343                                                   
344         return ret;                               
345 }                                                 
346                                                   
347 static noinline int flush_new_cached_update(st    
348                                             st    
349                                             en    
350                                             un    
351 {                                                 
352         struct bkey k;                            
353         int ret;                                  
354                                                   
355         btree_path_idx_t path_idx =               
356                 bch2_path_get(trans, i->btree_    
357                               BTREE_ITER_inten    
358         ret = bch2_btree_path_traverse(trans,     
359         if (ret)                                  
360                 goto out;                         
361                                                   
362         struct btree_path *btree_path = trans-    
363                                                   
364         /*                                        
365          * The old key in the insert entry mig    
366          * key in the btree that has been dele    
367          * flushed. Check for this and skip th    
368          * against a stale key.                   
369          */                                       
370         bch2_btree_path_peek_slot_exact(btree_    
371         if (!bkey_deleted(&k))                    
372                 goto out;                         
373                                                   
374         i->key_cache_already_flushed = true;      
375         i->flags |= BTREE_TRIGGER_norun;          
376                                                   
377         btree_path_set_should_be_locked(trans,    
378         ret = bch2_trans_update_by_path(trans,    
379 out:                                              
380         bch2_path_put(trans, path_idx, true);     
381         return ret;                               
382 }                                                 
383                                                   
384 static int __must_check                           
385 bch2_trans_update_by_path(struct btree_trans *    
386                           struct bkey_i *k, en    
387                           unsigned long ip)       
388 {                                                 
389         struct bch_fs *c = trans->c;              
390         struct btree_insert_entry *i, n;          
391         int cmp;                                  
392                                                   
393         struct btree_path *path = trans->paths    
394         EBUG_ON(!path->should_be_locked);         
395         EBUG_ON(trans->nr_updates >= trans->nr    
396         EBUG_ON(!bpos_eq(k->k.p, path->pos));     
397                                                   
398         n = (struct btree_insert_entry) {         
399                 .flags          = flags,          
400                 .bkey_type      = __btree_node    
401                 .btree_id       = path->btree_    
402                 .level          = path->level,    
403                 .cached         = path->cached    
404                 .path           = path_idx,       
405                 .k              = k,              
406                 .ip_allocated   = ip,             
407         };                                        
408                                                   
409 #ifdef CONFIG_BCACHEFS_DEBUG                      
410         trans_for_each_update(trans, i)           
411                 BUG_ON(i != trans->updates &&     
412                        btree_insert_entry_cmp(    
413 #endif                                            
414                                                   
415         /*                                        
416          * Pending updates are kept sorted: fi    
417          * then delete/trim any updates the ne    
418          */                                       
419         for (i = trans->updates; i < trans->up    
420                 cmp = btree_insert_entry_cmp(&    
421                 if (cmp <= 0)                     
422                         break;                    
423         }                                         
424                                                   
425         bool overwrite = !cmp && i < trans->up    
426                                                   
427         if (overwrite) {                          
428                 EBUG_ON(i->insert_trigger_run     
429                                                   
430                 bch2_path_put(trans, i->path,     
431                 i->flags        = n.flags;        
432                 i->cached       = n.cached;       
433                 i->k            = n.k;            
434                 i->path         = n.path;         
435                 i->ip_allocated = n.ip_allocat    
436         } else {                                  
437                 array_insert_item(trans->updat    
438                                   i - trans->u    
439                                                   
440                 i->old_v = bch2_btree_path_pee    
441                 i->old_btree_u64s = !bkey_dele    
442                                                   
443                 if (unlikely(trans->journal_re    
444                         struct bkey_i *j_k =      
445                                 bch2_journal_k    
446                                                   
447                         if (j_k) {                
448                                 i->old_k = j_k    
449                                 i->old_v = &j_    
450                         }                         
451                 }                                 
452         }                                         
453                                                   
454         __btree_path_get(trans, trans->paths +    
455                                                   
456         trace_update_by_path(trans, path, i, o    
457                                                   
458         /*                                        
459          * If a key is present in the key cach    
460          * btree - this is necessary for cache    
461          * a btree that's cached in the key ca    
462          * the key cache - but the key has to     
463          * work:                                  
464          */                                       
465         if (path->cached && !i->old_btree_u64s    
466                 return flush_new_cached_update    
467                                                   
468         return 0;                                 
469 }                                                 
470                                                   
471 static noinline int bch2_trans_update_get_key_    
472                                                   
473                                                   
474 {                                                 
475         struct btree_path *key_cache_path = bt    
476                                                   
477         if (!key_cache_path ||                    
478             !key_cache_path->should_be_locked     
479             !bpos_eq(key_cache_path->pos, iter    
480                 struct bkey_cached *ck;           
481                 int ret;                          
482                                                   
483                 if (!iter->key_cache_path)        
484                         iter->key_cache_path =    
485                                 bch2_path_get(    
486                                                   
487                                                   
488                                                   
489                 iter->key_cache_path =            
490                         bch2_btree_path_set_po    
491                                                   
492                                                   
493                                                   
494                 ret = bch2_btree_path_traverse    
495                 if (unlikely(ret))                
496                         return ret;               
497                                                   
498                 ck = (void *) trans->paths[ite    
499                                                   
500                 if (test_bit(BKEY_CACHED_DIRTY    
501                         trace_and_count(trans-    
502                         return btree_trans_res    
503                 }                                 
504                                                   
505                 btree_path_set_should_be_locke    
506         }                                         
507                                                   
508         return 0;                                 
509 }                                                 
510                                                   
511 int __must_check bch2_trans_update(struct btre    
512                                    struct bkey    
513 {                                                 
514         btree_path_idx_t path_idx = iter->upda    
515         int ret;                                  
516                                                   
517         if (iter->flags & BTREE_ITER_is_extent    
518                 return bch2_trans_update_exten    
519                                                   
520         if (bkey_deleted(&k->k) &&                
521             !(flags & BTREE_UPDATE_key_cache_r    
522             (iter->flags & BTREE_ITER_filter_s    
523                 ret = need_whiteout_for_snapsh    
524                 if (unlikely(ret < 0))            
525                         return ret;               
526                                                   
527                 if (ret)                          
528                         k->k.type = KEY_TYPE_w    
529         }                                         
530                                                   
531         /*                                        
532          * Ensure that updates to cached btree    
533          */                                       
534         struct btree_path *path = trans->paths    
535         if (!(flags & BTREE_UPDATE_key_cache_r    
536             !path->cached &&                      
537             !path->level &&                       
538             btree_id_cached(trans->c, path->bt    
539                 ret = bch2_trans_update_get_ke    
540                 if (ret)                          
541                         return ret;               
542                                                   
543                 path_idx = iter->key_cache_pat    
544         }                                         
545                                                   
546         return bch2_trans_update_by_path(trans    
547 }                                                 
548                                                   
549 int bch2_btree_insert_clone_trans(struct btree    
550                                   enum btree_i    
551                                   struct bkey_    
552 {                                                 
553         struct bkey_i *n = bch2_trans_kmalloc(    
554         int ret = PTR_ERR_OR_ZERO(n);             
555         if (ret)                                  
556                 return ret;                       
557                                                   
558         bkey_copy(n, k);                          
559         return bch2_btree_insert_trans(trans,     
560 }                                                 
561                                                   
562 struct jset_entry *__bch2_trans_jset_entry_all    
563 {                                                 
564         unsigned new_top = trans->journal_entr    
565         unsigned old_size = trans->journal_ent    
566                                                   
567         if (new_top > trans->journal_entries_s    
568                 trans->journal_entries_size =     
569                                                   
570                 btree_trans_stats(trans)->jour    
571         }                                         
572                                                   
573         struct jset_entry *n =                    
574                 bch2_trans_kmalloc_nomemzero(t    
575                                 trans->journal    
576         if (IS_ERR(n))                            
577                 return ERR_CAST(n);               
578                                                   
579         if (trans->journal_entries)               
580                 memcpy(n, trans->journal_entri    
581         trans->journal_entries = n;               
582                                                   
583         struct jset_entry *e = btree_trans_jou    
584         trans->journal_entries_u64s = new_top;    
585         return e;                                 
586 }                                                 
587                                                   
588 int bch2_bkey_get_empty_slot(struct btree_tran    
589                              enum btree_id btr    
590 {                                                 
591         struct bkey_s_c k;                        
592         int ret = 0;                              
593                                                   
594         bch2_trans_iter_init(trans, iter, btre    
595         k = bch2_btree_iter_prev(iter);           
596         ret = bkey_err(k);                        
597         if (ret)                                  
598                 goto err;                         
599                                                   
600         bch2_btree_iter_advance(iter);            
601         k = bch2_btree_iter_peek_slot(iter);      
602         ret = bkey_err(k);                        
603         if (ret)                                  
604                 goto err;                         
605                                                   
606         BUG_ON(k.k->type != KEY_TYPE_deleted);    
607                                                   
608         if (bkey_gt(k.k->p, end)) {               
609                 ret = -BCH_ERR_ENOSPC_btree_sl    
610                 goto err;                         
611         }                                         
612                                                   
613         return 0;                                 
614 err:                                              
615         bch2_trans_iter_exit(trans, iter);        
616         return ret;                               
617 }                                                 
618                                                   
619 void bch2_trans_commit_hook(struct btree_trans    
620                             struct btree_trans    
621 {                                                 
622         h->next = trans->hooks;                   
623         trans->hooks = h;                         
624 }                                                 
625                                                   
626 int bch2_btree_insert_nonextent(struct btree_t    
627                                 enum btree_id     
628                                 enum btree_ite    
629 {                                                 
630         struct btree_iter iter;                   
631         int ret;                                  
632                                                   
633         bch2_trans_iter_init(trans, &iter, btr    
634                              BTREE_ITER_cached    
635                              BTREE_ITER_not_ex    
636                              BTREE_ITER_intent    
637         ret   = bch2_btree_iter_traverse(&iter    
638                 bch2_trans_update(trans, &iter    
639         bch2_trans_iter_exit(trans, &iter);       
640         return ret;                               
641 }                                                 
642                                                   
643 int bch2_btree_insert_trans(struct btree_trans    
644                             struct bkey_i *k,     
645 {                                                 
646         struct btree_iter iter;                   
647         bch2_trans_iter_init(trans, &iter, id,    
648                              BTREE_ITER_intent    
649         int ret = bch2_btree_iter_traverse(&it    
650                   bch2_trans_update(trans, &it    
651         bch2_trans_iter_exit(trans, &iter);       
652         return ret;                               
653 }                                                 
654                                                   
655 /**                                               
656  * bch2_btree_insert - insert keys into the ex    
657  * @c:                  pointer to struct bch_    
658  * @id:                 btree to insert into      
659  * @k:                  key to insert             
660  * @disk_res:           must be non-NULL whene    
661  *                      splitting data extents    
662  * @flags:              transaction commit fla    
663  * @iter_flags:         btree iter update trig    
664  *                                                
665  * Returns:             0 on success, error co    
666  */                                               
667 int bch2_btree_insert(struct bch_fs *c, enum b    
668                       struct disk_reservation     
669                       enum btree_iter_update_t    
670 {                                                 
671         return bch2_trans_commit_do(c, disk_re    
672                              bch2_btree_insert    
673 }                                                 
674                                                   
675 int bch2_btree_delete_extent_at(struct btree_t    
676                                 unsigned len,     
677 {                                                 
678         struct bkey_i *k;                         
679                                                   
680         k = bch2_trans_kmalloc(trans, sizeof(*    
681         if (IS_ERR(k))                            
682                 return PTR_ERR(k);                
683                                                   
684         bkey_init(&k->k);                         
685         k->k.p = iter->pos;                       
686         bch2_key_resize(&k->k, len);              
687         return bch2_trans_update(trans, iter,     
688 }                                                 
689                                                   
690 int bch2_btree_delete_at(struct btree_trans *t    
691                          struct btree_iter *it    
692 {                                                 
693         return bch2_btree_delete_extent_at(tra    
694 }                                                 
695                                                   
696 int bch2_btree_delete(struct btree_trans *tran    
697                       enum btree_id btree, str    
698                       unsigned update_flags)      
699 {                                                 
700         struct btree_iter iter;                   
701         int ret;                                  
702                                                   
703         bch2_trans_iter_init(trans, &iter, btr    
704                              BTREE_ITER_cached    
705                              BTREE_ITER_intent    
706         ret   = bch2_btree_iter_traverse(&iter    
707                 bch2_btree_delete_at(trans, &i    
708         bch2_trans_iter_exit(trans, &iter);       
709                                                   
710         return ret;                               
711 }                                                 
712                                                   
713 int bch2_btree_delete_range_trans(struct btree    
714                                   struct bpos     
715                                   unsigned upd    
716                                   u64 *journal    
717 {                                                 
718         u32 restart_count = trans->restart_cou    
719         struct btree_iter iter;                   
720         struct bkey_s_c k;                        
721         int ret = 0;                              
722                                                   
723         bch2_trans_iter_init(trans, &iter, id,    
724         while ((k = bch2_btree_iter_peek_upto(    
725                 struct disk_reservation disk_r    
726                         bch2_disk_reservation_    
727                 struct bkey_i delete;             
728                                                   
729                 ret = bkey_err(k);                
730                 if (ret)                          
731                         goto err;                 
732                                                   
733                 bkey_init(&delete.k);             
734                                                   
735                 /*                                
736                  * This could probably be more    
737                  */                               
738                                                   
739                 /*                                
740                  * For extents, iter.pos won't    
741                  * bkey_start_pos(k.k) (for no    
742                  * same). It's important that     
743                  * because the range we want t    
744                  * of k.                          
745                  *                                
746                  * (bch2_btree_iter_peek() doe    
747                  * bkey_start_pos(k.k)).          
748                  */                               
749                 delete.k.p = iter.pos;            
750                                                   
751                 if (iter.flags & BTREE_ITER_is    
752                         bch2_key_resize(&delet    
753                                         bpos_m    
754                                         iter.p    
755                                                   
756                 ret   = bch2_trans_update(tran    
757                         bch2_trans_commit(tran    
758                                           BCH_    
759                 bch2_disk_reservation_put(tran    
760 err:                                              
761                 /*                                
762                  * the bch2_trans_begin() call    
763                  * need to call it after every    
764                  * overflow, but don't want to    
765                  * is a no-op and we have no w    
766                  */                               
767                 bch2_trans_begin(trans);          
768                                                   
769                 if (bch2_err_matches(ret, BCH_    
770                         ret = 0;                  
771                 if (ret)                          
772                         break;                    
773         }                                         
774         bch2_trans_iter_exit(trans, &iter);       
775                                                   
776         return ret ?: trans_was_restarted(tran    
777 }                                                 
778                                                   
779 /*                                                
780  * bch_btree_delete_range - delete everything     
781  *                                                
782  * Range is a half open interval - [start, end    
783  */                                               
784 int bch2_btree_delete_range(struct bch_fs *c,     
785                             struct bpos start,    
786                             unsigned update_fl    
787                             u64 *journal_seq)     
788 {                                                 
789         int ret = bch2_trans_run(c,               
790                         bch2_btree_delete_rang    
791                                                   
792         if (ret == -BCH_ERR_transaction_restar    
793                 ret = 0;                          
794         return ret;                               
795 }                                                 
796                                                   
797 int bch2_btree_bit_mod(struct btree_trans *tra    
798                        struct bpos pos, bool s    
799 {                                                 
800         struct bkey_i *k = bch2_trans_kmalloc(    
801         int ret = PTR_ERR_OR_ZERO(k);             
802         if (ret)                                  
803                 return ret;                       
804                                                   
805         bkey_init(&k->k);                         
806         k->k.type = set ? KEY_TYPE_set : KEY_T    
807         k->k.p = pos;                             
808                                                   
809         struct btree_iter iter;                   
810         bch2_trans_iter_init(trans, &iter, btr    
811                                                   
812         ret   = bch2_btree_iter_traverse(&iter    
813                 bch2_trans_update(trans, &iter    
814         bch2_trans_iter_exit(trans, &iter);       
815         return ret;                               
816 }                                                 
817                                                   
818 int bch2_btree_bit_mod_buffered(struct btree_t    
819                                 struct bpos po    
820 {                                                 
821         struct bkey_i k;                          
822                                                   
823         bkey_init(&k.k);                          
824         k.k.type = set ? KEY_TYPE_set : KEY_TY    
825         k.k.p = pos;                              
826                                                   
827         return bch2_trans_update_buffered(tran    
828 }                                                 
829                                                   
830 static int __bch2_trans_log_msg(struct btree_t    
831 {                                                 
832         struct jset_entry *e = bch2_trans_jset    
833         int ret = PTR_ERR_OR_ZERO(e);             
834         if (ret)                                  
835                 return ret;                       
836                                                   
837         struct jset_entry_log *l = container_o    
838         journal_entry_init(e, BCH_JSET_ENTRY_l    
839         memcpy(l->d, buf->buf, buf->pos);         
840         return 0;                                 
841 }                                                 
842                                                   
843 __printf(3, 0)                                    
844 static int                                        
845 __bch2_fs_log_msg(struct bch_fs *c, unsigned c    
846                   va_list args)                   
847 {                                                 
848         struct printbuf buf = PRINTBUF;           
849         prt_vprintf(&buf, fmt, args);             
850                                                   
851         unsigned u64s = DIV_ROUND_UP(buf.pos,     
852         prt_chars(&buf, '\0', u64s * sizeof(u6    
853                                                   
854         int ret = buf.allocation_failure ? -BC    
855         if (ret)                                  
856                 goto err;                         
857                                                   
858         if (!test_bit(JOURNAL_running, &c->jou    
859                 ret = darray_make_room(&c->jou    
860                 if (ret)                          
861                         goto err;                 
862                                                   
863                 struct jset_entry_log *l = (vo    
864                 journal_entry_init(&l->entry,     
865                 memcpy(l->d, buf.buf, buf.pos)    
866                 c->journal.early_journal_entri    
867         } else {                                  
868                 ret = bch2_trans_commit_do(c,     
869                         BCH_TRANS_COMMIT_lazy_    
870                         __bch2_trans_log_msg(t    
871         }                                         
872 err:                                              
873         printbuf_exit(&buf);                      
874         return ret;                               
875 }                                                 
876                                                   
877 __printf(2, 3)                                    
878 int bch2_fs_log_msg(struct bch_fs *c, const ch    
879 {                                                 
880         va_list args;                             
881         int ret;                                  
882                                                   
883         va_start(args, fmt);                      
884         ret = __bch2_fs_log_msg(c, 0, fmt, arg    
885         va_end(args);                             
886         return ret;                               
887 }                                                 
888                                                   
889 /*                                                
890  * Use for logging messages during recovery to    
891  * blocking.                                      
892  */                                               
893 __printf(2, 3)                                    
894 int bch2_journal_log_msg(struct bch_fs *c, con    
895 {                                                 
896         va_list args;                             
897         int ret;                                  
898                                                   
899         va_start(args, fmt);                      
900         ret = __bch2_fs_log_msg(c, BCH_WATERMA    
901         va_end(args);                             
902         return ret;                               
903 }                                                 
904                                                   

~ [ 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