static int set_ufs_info(const struct ufs_super_block *sb, partition_t *partition) { partition->fsname[0]='\0'; partition->info[0]='\0'; switch(partition->upart_type) { case UP_UFS_LE: case UP_UFS2_LE: partition->blocksize=le32(sb->fs_fsize); break; default: partition->blocksize=be32(sb->fs_fsize); } switch(partition->upart_type) { case UP_UFS: case UP_UFS_LE: default: set_part_name(partition,(const char*)sb->fs_u11.fs_u1.fs_fsmnt,sizeof(partition->fsname)); snprintf(partition->info, sizeof(partition->info), "UFS1 blocksize=%u", partition->blocksize); break; case UP_UFS2: case UP_UFS2_LE: set_part_name(partition,(const char*)sb->fs_u11.fs_u2.fs_fsmnt,sizeof(partition->fsname)); snprintf(partition->info, sizeof(partition->info), "UFS2 blocksize=%u", partition->blocksize); break; } return 0; }
int recover_BSD(disk_t *disk_car, const struct disklabel*bsd_header,partition_t *partition,const int verbose, const int dump_ind) { int i; int i_max_p_offset=-1; if(test_BSD(disk_car,bsd_header,partition,verbose,dump_ind,BSD_MAXPARTITIONS)==0) { partition->upart_type=UP_FREEBSD; for(i=0;i<BSD_MAXPARTITIONS;i++) { if(bsd_header->d_partitions[i].p_fstype>0) { if(i_max_p_offset==-1 || le32(bsd_header->d_partitions[i].p_offset)>le32(bsd_header->d_partitions[i_max_p_offset].p_offset)) i_max_p_offset=i; } } if(i_max_p_offset>=0) partition->part_size=(uint64_t)(le32(bsd_header->d_partitions[i_max_p_offset].p_size) + le32(bsd_header->d_partitions[i_max_p_offset].p_offset) - 1) * disk_car->sector_size - partition->part_offset; else partition->part_size=0; partition->part_type_i386=P_FREEBSD; set_part_name(partition,bsd_header->d_packname,16); partition->info[0]='\0'; return 0; } if(test_BSD(disk_car,bsd_header,partition,verbose,dump_ind,OPENBSD_MAXPARTITIONS)==0) { partition->upart_type=UP_OPENBSD; for(i=0;i<OPENBSD_MAXPARTITIONS;i++) { if(bsd_header->d_partitions[i].p_fstype>0) { if(i_max_p_offset==-1 || le32(bsd_header->d_partitions[i].p_offset)>le32(bsd_header->d_partitions[i_max_p_offset].p_offset)) i_max_p_offset=i; } } if(i_max_p_offset>=0) partition->part_size=(uint64_t)(le32(bsd_header->d_partitions[i_max_p_offset].p_size) + le32(bsd_header->d_partitions[i_max_p_offset].p_offset) - 1) * disk_car->sector_size - partition->part_offset; else partition->part_size=0; partition->part_type_i386=P_OPENBSD; set_part_name(partition,bsd_header->d_packname,16); partition->info[0]='\0'; return 0; } return 1; }
static int set_EXT2_info(const struct ext2_super_block *sb, partition_t *partition, const int verbose) { partition->blocksize=EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size); set_part_name(partition,sb->s_volume_name,16); /* sb->s_last_mounted seems to be unemployed in kernel 2.2.16 */ if(EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_HUGE_FILE)!=0 || EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_GDT_CSUM)!=0 || EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_DIR_NLINK)!=0 || EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)!=0 || EXT2_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_64BIT)!=0 || EXT2_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_MMP)!=0) snprintf(partition->info, sizeof(partition->info), "ext4 blocksize=%u", partition->blocksize); else if(EXT2_HAS_COMPAT_FEATURE(sb,EXT3_FEATURE_COMPAT_HAS_JOURNAL)!=0) snprintf(partition->info, sizeof(partition->info), "ext3 blocksize=%u", partition->blocksize); else snprintf(partition->info, sizeof(partition->info), "ext2 blocksize=%u", partition->blocksize); if(EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT2_FEATURE_RO_COMPAT_LARGE_FILE)!=0) strcat(partition->info," Large_file"); if(EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)!=0) strcat(partition->info," Sparse_SB"); if(EXT2_HAS_INCOMPAT_FEATURE(sb,EXT3_FEATURE_INCOMPAT_RECOVER)!=0) strcat(partition->info," Recover"); if(EXT2_HAS_INCOMPAT_FEATURE(sb,EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)!=0) strcat(partition->info," Journal_dev"); if(le16(sb->s_block_group_nr)!=0) { strcat(partition->info," Backup_SB"); if(verbose>0) { log_warning("\nblock_group_nr %u\n",le16(sb->s_block_group_nr)); } } /* last mounted => date */ return 0; }
static int set_xfs_info(const struct xfs_sb *sb, partition_t *partition) { partition->blocksize=be32(sb->sb_blocksize); partition->fsname[0]='\0'; partition->info[0]='\0'; switch(partition->upart_type) { case UP_XFS: snprintf(partition->info, sizeof(partition->info), "XFS <=6.1 blocksize=%u", partition->blocksize); break; case UP_XFS2: snprintf(partition->info, sizeof(partition->info), "XFS 6.2 - attributes blocksize=%u", partition->blocksize); break; case UP_XFS3: snprintf(partition->info, sizeof(partition->info), "XFS 6.2 - new inode version blocksize=%u", partition->blocksize); break; case UP_XFS4: snprintf(partition->info, sizeof(partition->info), "XFS 6.2+ - bitmap version blocksize=%u", partition->blocksize); break; default: return 1; } set_part_name(partition,sb->sb_fname,12); return 0; }
static int set_BeFS_info(const struct disk_super_block *beos_block, partition_t *partition) { partition->blocksize= 1 << le32(beos_block->block_shift); partition->info[0]='\0'; snprintf(partition->info, sizeof(partition->info), "BeFS blocksize=%u", partition->blocksize); set_part_name(partition,beos_block->name,B_OS_NAME_LENGTH); return 0; }
static int set_JFS_info(const struct jfs_superblock *sb, partition_t *partition) { partition->blocksize=le32(sb->s_bsize); snprintf(partition->info, sizeof(partition->info), "JFS %u, blocksize=%u", (unsigned int)le32(sb->s_version), partition->blocksize); partition->fsname[0]='\0'; if(le32(sb->s_version)==1) { set_part_name(partition,sb->s_fpack,11); } return 0; }
static void set_btrfs_info(const struct btrfs_super_block *sb, partition_t *partition) { partition->upart_type=UP_BTRFS; partition->blocksize=le32(sb->dev_item.sector_size); set_part_name(partition, sb->label, sizeof(sb->label)); snprintf(partition->info, sizeof(partition->info), "btrfs blocksize=%u", partition->blocksize); if(le64(sb->bytenr)!=partition->part_offset + BTRFS_SUPER_INFO_OFFSET) { strcat(partition->info," Backup superblock"); } /* last mounted => date */ }
static int set_rfs_info(const struct reiserfs_super_block *sb, partition_t *partition) { partition->fsname[0]='\0'; partition->blocksize=le16(sb->s_blocksize); switch(partition->upart_type) { case UP_RFS: snprintf(partition->info, sizeof(partition->info), "ReiserFS 3.5 with standard journal blocksize=%u", partition->blocksize); break; case UP_RFS2: snprintf(partition->info, sizeof(partition->info), "ReiserFS 3.6 with standard journal blocksize=%u", partition->blocksize); set_part_name(partition,(const char*)sb->s_label,16); break; case UP_RFS3: if(le16(sb->sb_version)==1) snprintf(partition->info, sizeof(partition->info), "ReiserFS 3.5 with non standard journal blocksize=%u", partition->blocksize); else if(le16(sb->sb_version)==2) snprintf(partition->info, sizeof(partition->info), "ReiserFS 3.6 with non standard journal blocksize=%u", partition->blocksize); else snprintf(partition->info, sizeof(partition->info), "ReiserFS 3.? with non standard journal blocksize=%u", partition->blocksize); set_part_name(partition,(const char*)sb->s_label,16); break; default: partition->info[0]='\0'; return 1; } if (le16(sb->s_state) == REISERFS_ERROR_FS) { strcat(partition->info,", need recovery"); } return 0; }
static int set_cramfs_info(const struct cramfs_super *sb, partition_t *partition) { set_part_name(partition, (const char*)sb->name, 16); switch(partition->upart_type) { case UP_CRAMFS: strncpy(partition->info,"cramfs",sizeof(partition->info)); break; default: partition->info[0]='\0'; return 1; } return 0; }
static void set_rfs_info(const struct reiserfs_super_block *sb, partition_t *partition) { partition->fsname[0]='\0'; partition->blocksize=le16(sb->s_blocksize); if (memcmp(sb->s_magic,REISERFS_SUPER_MAGIC,sizeof(REISERFS_SUPER_MAGIC)) == 0) { partition->upart_type = UP_RFS; snprintf(partition->info, sizeof(partition->info), "ReiserFS 3.5 with standard journal blocksize=%u", partition->blocksize); } else if(memcmp(sb->s_magic,REISERFS2_SUPER_MAGIC,sizeof(REISERFS2_SUPER_MAGIC)) == 0) { partition->upart_type = UP_RFS2; snprintf(partition->info, sizeof(partition->info), "ReiserFS 3.6 with standard journal blocksize=%u", partition->blocksize); set_part_name(partition,(const char*)sb->s_label,16); } else if(memcmp(sb->s_magic,REISERFS3_SUPER_MAGIC,sizeof(REISERFS3_SUPER_MAGIC)) == 0) { partition->upart_type = UP_RFS3; if(le16(sb->sb_version)==1) snprintf(partition->info, sizeof(partition->info), "ReiserFS 3.5 with non standard journal blocksize=%u", partition->blocksize); else if(le16(sb->sb_version)==2) snprintf(partition->info, sizeof(partition->info), "ReiserFS 3.6 with non standard journal blocksize=%u", partition->blocksize); else snprintf(partition->info, sizeof(partition->info), "ReiserFS 3.? with non standard journal blocksize=%u", partition->blocksize); set_part_name(partition,(const char*)sb->s_label,16); } if(le16(sb->s_state) == REISERFS_ERROR_FS) { strcat(partition->info,", need recovery"); } }
int check_BSD(disk_t *disk_car,partition_t *partition,const int verbose, const unsigned int max_partitions) { unsigned char *buffer; buffer=(unsigned char*)MALLOC(BSD_DISKLABEL_SIZE); if(disk_car->pread(disk_car, buffer, BSD_DISKLABEL_SIZE, partition->part_offset + 0x200) != BSD_DISKLABEL_SIZE) { free(buffer); return 1; } if(test_BSD(disk_car,(const struct disklabel*)buffer,partition,verbose,0,max_partitions)) { free(buffer); return 1; } set_part_name(partition,((const struct disklabel*)buffer)->d_packname,16); free(buffer); return 0; }
static void set_xfs_info(const struct xfs_sb *sb, partition_t *partition) { partition->blocksize=be32(sb->sb_blocksize); partition->fsname[0]='\0'; partition->info[0]='\0'; switch(be16(sb->sb_versionnum) & XFS_SB_VERSION_NUMBITS) { case XFS_SB_VERSION_1: partition->upart_type = UP_XFS; snprintf(partition->info, sizeof(partition->info), "XFS <=6.1, blocksize=%u", partition->blocksize); break; case XFS_SB_VERSION_2: partition->upart_type = UP_XFS2; snprintf(partition->info, sizeof(partition->info), "XFS 6.2 - attributes, blocksize=%u", partition->blocksize); break; case XFS_SB_VERSION_3: partition->upart_type = UP_XFS3; snprintf(partition->info, sizeof(partition->info), "XFS 6.2 - new inode version, blocksize=%u", partition->blocksize); break; case XFS_SB_VERSION_4: partition->upart_type = UP_XFS4; snprintf(partition->info, sizeof(partition->info), "XFS 6.2+ - bitmap version, blocksize=%u", partition->blocksize); break; case XFS_SB_VERSION_5: partition->upart_type = UP_XFS5; snprintf(partition->info, sizeof(partition->info), "XFS CRC enabled, blocksize=%u", partition->blocksize); break; default: snprintf(partition->info, sizeof(partition->info), "XFS unknown version %u\n", be16(sb->sb_versionnum)& XFS_SB_VERSION_NUMBITS); break; } set_part_name(partition,sb->sb_fname,12); }
static void set_MD_info_be(const struct mdp_superblock_s *sb, partition_t *partition, const int verbose) { if(be32(sb->major_version)==0) { unsigned int i; partition->upart_type=UP_MD; sprintf(partition->fsname,"md%u",(unsigned int)be32(sb->md_minor)); sprintf(partition->info,"md %u.%u.%u B.Endian Raid %u: devices", (unsigned int)be32(sb->major_version), (unsigned int)be32(sb->minor_version), (unsigned int)be32(sb->patch_version), (unsigned int)be32(sb->level)); for(i=0;i<MD_SB_DISKS;i++) { if(be32(sb->disks[i].major)!=0 && be32(sb->disks[i].minor)!=0) { if(strlen(partition->info)<sizeof(partition->info)-26) { sprintf(&partition->info[strlen(partition->info)]," %u(%u,%u)", (unsigned int)be32(sb->disks[i].number), (unsigned int)be32(sb->disks[i].major), (unsigned int)be32(sb->disks[i].minor)); if(be32(sb->disks[i].major)==be32(sb->this_disk.major) && be32(sb->disks[i].minor)==be32(sb->this_disk.minor)) sprintf(&partition->info[strlen(partition->info)],"*"); } } } } else { const struct mdp_superblock_1 *sb1=(const struct mdp_superblock_1 *)sb; partition->upart_type=UP_MD1; set_part_name(partition,sb1->set_name,32); sprintf(partition->info,"md %u.x B.Endian Raid %u - Array Slot : %lu", (unsigned int)be32(sb1->major_version), (unsigned int)be32(sb1->level), (long unsigned)be32(sb1->dev_number)); if(be32(sb1->max_dev) <= 384) { unsigned int i,d; for (i= be32(sb1->max_dev); i> 0 ; i--) if (be16(sb1->dev_roles[i-1]) != 0xffff) break; strcat(partition->info, " ("); for (d=0; d < i && strlen(partition->info) < sizeof(partition->info) - 9; d++) { const int role = be16(sb1->dev_roles[d]); if (d) strcat(partition->info, ", "); if (role == 0xffff) strcat(partition->info, "empty"); else if(role == 0xfffe) strcat(partition->info, "failed"); else sprintf(&partition->info[strlen(partition->info)], "%d", role); } strcat(partition->info, ")"); } } if(verbose>0) log_info("%s %s\n", partition->fsname, partition->info); }