1 #include "block_list.h" 2 #include "block_range.h" 3 #include <stdio.h> 4 #include <sys/types.h> 5 #include <sys/stat.h> 6 #include <fcntl.h> 7 8 struct block_list { 9 FILE *f; 10 const char *mountpoint; 11 12 struct { 13 const char *filename; 14 struct block_range *head; 15 struct block_range *tail; 16 } entry; 17 }; 18 19 static void *init(const char *file, const char *mountpoint) 20 { 21 struct block_list *params = malloc(sizeof(*params)); 22 23 if (!params) 24 return NULL; 25 params->mountpoint = mountpoint; 26 params->f = fopen(file, "w+"); 27 if (!params->f) { 28 free(params); 29 return NULL; 30 } 31 return params; 32 } 33 34 static int start_new_file(char *path, ext2_ino_t ino EXT2FS_ATTR((unused)), 35 struct ext2_inode *inode EXT2FS_ATTR((unused)), 36 void *data) 37 { 38 struct block_list *params = data; 39 40 params->entry.head = params->entry.tail = NULL; 41 params->entry.filename = LINUX_S_ISREG(inode->i_mode) ? path : NULL; 42 return 0; 43 } 44 45 static int add_block(ext2_filsys fs EXT2FS_ATTR((unused)), blk64_t blocknr, 46 int metadata, void *data) 47 { 48 struct block_list *params = data; 49 50 if (params->entry.filename && !metadata) 51 add_blocks_to_range(¶ms->entry.head, ¶ms->entry.tail, 52 blocknr, blocknr); 53 return 0; 54 } 55 56 static int inline_data(void *inline_data EXT2FS_ATTR((unused)), 57 void *data EXT2FS_ATTR((unused))) 58 { 59 return 0; 60 } 61 62 static int end_new_file(void *data) 63 { 64 struct block_list *params = data; 65 66 if (!params->entry.filename || !params->entry.head) 67 return 0; 68 if (fprintf(params->f, "%s%s ", params->mountpoint, 69 params->entry.filename) < 0 70 || write_block_ranges(params->f, params->entry.head, " ") 71 || fwrite("\n", 1, 1, params->f) != 1) 72 return -1; 73 74 delete_block_ranges(params->entry.head); 75 return 0; 76 } 77 78 static int cleanup(void *data) 79 { 80 struct block_list *params = data; 81 82 fclose(params->f); 83 free(params); 84 return 0; 85 } 86 87 struct fsmap_format block_list_format = { 88 .init = init, 89 .start_new_file = start_new_file, 90 .add_block = add_block, 91 .inline_data = inline_data, 92 .end_new_file = end_new_file, 93 .cleanup = cleanup, 94 }; 95