1 /* 2 * sparse.c --- find the groups in an ext2 filesystem with metadata backups 3 * 4 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o. 5 * Copyright (C) 2002 Andreas Dilger. 6 * 7 * %Begin-Header% 8 * This file may be redistributed under the terms of the GNU Library 9 * General Public License, version 2. 10 * %End-Header% 11 */ 12 13 #include <stdio.h> 14 15 #include "ext2_fs.h" 16 #include "ext2fsP.h" 17 18 static int test_root(int a, int b) 19 { 20 if (a == 0) 21 return 1; 22 while (1) { 23 if (a == 1) 24 return 1; 25 if (a % b) 26 return 0; 27 a = a / b; 28 } 29 } 30 31 int ext2fs_bg_has_super(ext2_filsys fs, int group_block) 32 { 33 if (!(fs->super->s_feature_ro_compat & 34 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) 35 return 1; 36 37 if (test_root(group_block, 3) || (test_root(group_block, 5)) || 38 test_root(group_block, 7)) 39 return 1; 40 41 return 0; 42 } 43 44 /* 45 * Iterate through the groups which hold BACKUP superblock/GDT copies in an 46 * ext3 filesystem. The counters should be initialized to 1, 5, and 7 before 47 * calling this for the first time. In a sparse filesystem it will be the 48 * sequence of powers of 3, 5, and 7: 1, 3, 5, 7, 9, 25, 27, 49, 81, ... 49 * For a non-sparse filesystem it will be every group: 1, 2, 3, 4, ... 50 */ 51 unsigned int ext2fs_list_backups(ext2_filsys fs, unsigned int *three, 52 unsigned int *five, unsigned int *seven) 53 { 54 unsigned int *min = three; 55 int mult = 3; 56 unsigned int ret; 57 58 if (!(fs->super->s_feature_ro_compat & 59 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) { 60 ret = *min; 61 *min += 1; 62 return ret; 63 } 64 65 if (*five < *min) { 66 min = five; 67 mult = 5; 68 } 69 if (*seven < *min) { 70 min = seven; 71 mult = 7; 72 } 73 74 ret = *min; 75 *min *= mult; 76 77 return ret; 78 } 79