1/* 2 * Copyright 2016, NICTA 3 * 4 * This software may be distributed and modified according to the terms of 5 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 6 * See "LICENSE_GPLv2.txt" for details. 7 * 8 * @TAG(NICTA_GPL) 9 */ 10 11#include <bilbyfs.h> 12 13int gc_init(struct bilbyfs_info *bi) 14{ 15 bi->gc_buf.buf = vmalloc(bi->super.leb_size); 16 if (bi->gc_buf.buf) { 17 bi->gc_buf.size = bi->super.leb_size; 18 return 0; 19 } 20 return -ENOMEM; 21} 22 23void gc_clean(struct bilbyfs_info *bi) 24{ 25 vfree(bi->gc_buf.buf); 26} 27 28int gc_garbage_collect(struct bilbyfs_info *bi) 29{ 30 int err, i; 31 int lnum; 32 int list_limit = BILBYFS_MAX_OBJ_PER_TRANS; 33 struct obj_ch *obj; 34 struct obj_ch **list, **valid_list; 35 int count = 0, valid_count = 0; 36 37 bilbyfs_err("bilbyfs GC\n"); 38 bilbyfs_debug("gc_garbage_collect() starts\n"); 39 40 /* Find block with most garbage */ 41 lnum = fsm_get_dirtiest_eb(bi); 42 if (lnum < 0) { 43 bilbyfs_debug("gc_garbage_collect() : No erase-block to garbage collect.\n"); 44 return -ENOENT; 45 } 46 47 // Scan erase-block to build object lists 48 list = kmalloc(sizeof(struct obj_ch *) *list_limit); 49 if (!list) 50 return -ENOMEM; 51 count = ostore_scan_leb_obj(bi, &bi->gc_buf, lnum, (void **) list, list_limit); 52 if (count < 0) { 53 kfree(list); 54 return count; 55 } 56 57 valid_list = kmalloc(sizeof(struct obj_ch *) * list_limit); 58 if (!valid_list) { 59 kfree(list); 60 return -ENOMEM; 61 } 62 for (i = 0; i < count; i++) { 63 obj = list[i]; 64 if (!gim_is_removable(bi, obj)) { 65 valid_list[valid_count] = obj; 66 valid_count++; 67 } 68 } 69 70 /* Copy valid objects to new erase-block */ 71 if (valid_count > 0) { 72 err = ostore_write_obj_list(bi, (void **) valid_list, valid_count, OSW_GC | OSW_SYNC); 73 kfree(valid_list); 74 if (err) { 75 kfree(list); 76 return err; 77 } 78 } 79 80 err = ostore_erase(bi, lnum); 81 if (err) { 82 kfree(list); 83 kfree(valid_list); 84 return err; 85 } 86 87 for (i = 0; i < count; i++) 88 gim_garbage_collected(bi, list[i]); 89 90 bilbyfs_debug("gc_garbage_collect() Successfully clean up lnum=%d\n", lnum); 91 kfree(list); 92 return 0; 93} 94 95 96