diff options
Diffstat (limited to 'misc/e4defrag.c')
-rw-r--r-- | misc/e4defrag.c | 185 |
1 files changed, 18 insertions, 167 deletions
diff --git a/misc/e4defrag.c b/misc/e4defrag.c index 9008bc27..eea30571 100644 --- a/misc/e4defrag.c +++ b/misc/e4defrag.c @@ -163,101 +163,6 @@ struct frag_statistic_ino { char msg_buffer[PATH_MAX + 1]; /* pathname of the file */ }; -typedef __u16 __le16; -typedef __u32 __le32; -typedef __u64 __le64; - -/* - * Structure of the super block - */ -struct ext4_super_block { -/*00*/ __le32 s_inodes_count; /* Inodes count */ - __le32 s_blocks_count_lo; /* Blocks count */ - __le32 s_r_blocks_count_lo; /* Reserved blocks count */ - __le32 s_free_blocks_count_lo; /* Free blocks count */ -/*10*/ __le32 s_free_inodes_count; /* Free inodes count */ - __le32 s_first_data_block; /* First Data Block */ - __le32 s_log_block_size; /* Block size */ - __le32 s_obso_log_frag_size; /* Obsoleted fragment size */ -/*20*/ __le32 s_blocks_per_group; /* # Blocks per group */ - __le32 s_obso_frags_per_group; /* Obsoleted fragments per group */ - __le32 s_inodes_per_group; /* # Inodes per group */ - __le32 s_mtime; /* Mount time */ -/*30*/ __le32 s_wtime; /* Write time */ - __le16 s_mnt_count; /* Mount count */ - __le16 s_max_mnt_count; /* Maximal mount count */ - __le16 s_magic; /* Magic signature */ - __le16 s_state; /* File system state */ - __le16 s_errors; /* Behaviour when detecting errors */ - __le16 s_minor_rev_level; /* minor revision level */ -/*40*/ __le32 s_lastcheck; /* time of last check */ - __le32 s_checkinterval; /* max. time between checks */ - __le32 s_creator_os; /* OS */ - __le32 s_rev_level; /* Revision level */ -/*50*/ __le16 s_def_resuid; /* Default uid for reserved blocks */ - __le16 s_def_resgid; /* Default gid for reserved blocks */ - /* - * These fields are for EXT4_DYNAMIC_REV superblocks only. - * - * Note: the difference between the compatible feature set and - * the incompatible feature set is that if there is a bit set - * in the incompatible feature set that the kernel doesn't - * know about, it should refuse to mount the filesystem. - * - * e2fsck's requirements are more strict; if it doesn't know - * about a feature in either the compatible or incompatible - * feature set, it must abort and not try to meddle with - * things it doesn't understand... - */ - __le32 s_first_ino; /* First non-reserved inode */ - __le16 s_inode_size; /* size of inode structure */ - __le16 s_block_group_nr; /* block group # of this superblock */ - __le32 s_feature_compat; /* compatible feature set */ -/*60*/ __le32 s_feature_incompat; /* incompatible feature set */ - __le32 s_feature_ro_compat; /* readonly-compatible feature set */ -/*68*/ __u8 s_uuid[16]; /* 128-bit uuid for volume */ -/*78*/ char s_volume_name[16]; /* volume name */ -/*88*/ char s_last_mounted[64]; /* directory where last mounted */ -/*C8*/ __le32 s_algorithm_usage_bitmap; /* For compression */ - /* - * Performance hints. Directory preallocation should only - * happen if the EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on. - */ - __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ - __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ - __le16 s_reserved_gdt_blocks; /* Per group desc for online growth */ - /* - * Journaling support valid if EXT4_FEATURE_COMPAT_HAS_JOURNAL set. - */ -/*D0*/ __u8 s_journal_uuid[16]; /* uuid of journal superblock */ -/*E0*/ __le32 s_journal_inum; /* inode number of journal file */ - __le32 s_journal_dev; /* device number of journal file */ - __le32 s_last_orphan; /* start of list of inodes to delete */ - __le32 s_hash_seed[4]; /* HTREE hash seed */ - __u8 s_def_hash_version; /* Default hash version to use */ - __u8 s_reserved_char_pad; - __le16 s_desc_size; /* size of group descriptor */ -/*100*/ __le32 s_default_mount_opts; - __le32 s_first_meta_bg; /* First metablock block group */ - __le32 s_mkfs_time; /* When the filesystem was created */ - __le32 s_jnl_blocks[17]; /* Backup of the journal inode */ - /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */ -/*150*/ __le32 s_blocks_count_hi; /* Blocks count */ - __le32 s_r_blocks_count_hi; /* Reserved blocks count */ - __le32 s_free_blocks_count_hi; /* Free blocks count */ - __le16 s_min_extra_isize; /* All inodes have at least # bytes */ - __le16 s_want_extra_isize; /* New inodes should reserve # bytes */ - __le32 s_flags; /* Miscellaneous flags */ - __le16 s_raid_stride; /* RAID stride */ - __le16 s_mmp_interval; /* # seconds to wait in MMP checking */ - __le64 s_mmp_block; /* Block for multi-mount protection */ - __le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ - __u8 s_log_groups_per_flex; /* FLEX_BG group size */ - __u8 s_reserved_char_pad2; - __le16 s_reserved_pad; - __u32 s_reserved[162]; /* Padding to the end of the block */ -}; - char lost_found_dir[PATH_MAX + 1]; int block_size; int extents_before_defrag; @@ -271,8 +176,8 @@ unsigned int regular_count; unsigned int succeed_cnt; unsigned int total_count; __u8 log_groups_per_flex; -__le32 blocks_per_group; -__le32 feature_incompat; +__u32 blocks_per_group; +__u32 feature_incompat; ext4_fsblk_t files_block_count; struct frag_statistic_ino frag_rank[SHOW_FRAG_FILES]; @@ -392,7 +297,7 @@ static int get_mount_point(const char *devname, char *mount_point, * * @file: the file's name. */ -static int is_ext4(const char *file) +static int is_ext4(const char *file, char *devname) { int maxlen = 0; int len, ret; @@ -449,6 +354,7 @@ static int is_ext4(const char *file) memset(mnt_type, 0, strlen(mnt->mnt_type) + 1); strncpy(mnt_type, mnt->mnt_type, strlen(mnt->mnt_type)); strncpy(lost_found_dir, mnt->mnt_dir, PATH_MAX); + strncpy(devname, mnt->mnt_fsname, strlen(mnt->mnt_fsname) + 1); } endmntent(fp); @@ -1128,67 +1034,6 @@ static void free_exts_group(struct fiemap_extent_group *ext_group_head) } /* - * get_superblock_info() - Get superblock info by the file name. - * - * @file: the file's name. - * @sb: the pointer of the struct ext4_super_block. - */ -static int get_superblock_info(const char *file, struct ext4_super_block *sb) -{ - /* Refer to /etc/mtab */ - const char *mtab = MOUNTED; - FILE *fp = NULL; - - int fd = -1; - int ret; - size_t maxlen = 0; - size_t len; - char dev_name[PATH_MAX + 1]; - struct mntent *mnt = NULL; - - fp = setmntent(mtab, "r"); - if (fp == NULL) - return -1; - - while ((mnt = getmntent(fp)) != NULL) { - len = strlen(mnt->mnt_dir); - ret = memcmp(file, mnt->mnt_dir, len); - if (ret != 0) - continue; - - if (len < maxlen) - continue; - - maxlen = len; - - memset(dev_name, 0, PATH_MAX + 1); - strncpy(dev_name, mnt->mnt_fsname, - strnlen(mnt->mnt_fsname, PATH_MAX)); - } - - fd = open64(dev_name, O_RDONLY); - if (fd < 0) { - ret = -1; - goto out; - } - - /* Set offset to read superblock */ - ret = lseek64(fd, SUPERBLOCK_OFFSET, SEEK_SET); - if (ret < 0) - goto out; - - ret = read(fd, sb, sizeof(struct ext4_super_block)); - if (ret < 0) - goto out; - -out: - if (fd != -1) - close(fd); - endmntent(fp); - return ret; -} - -/* * get_best_count() - Get the file best extents count. * * @block_count: the file's physical block count. @@ -1854,13 +1699,14 @@ out: int main(int argc, char *argv[]) { int opt; - int i, j; + int i, j, ret = 0; int flags = FTW_PHYS | FTW_MOUNT; int arg_type = -1; int success_flag = 0; char dir_name[PATH_MAX + 1]; + char dev_name[PATH_MAX + 1]; struct stat64 buf; - struct ext4_super_block sb; + ext2_filsys fs = NULL; /* Parse arguments */ if (argc == 1) @@ -1900,6 +1746,7 @@ int main(int argc, char *argv[]) log_groups_per_flex = 0; memset(dir_name, 0, PATH_MAX + 1); + memset(dev_name, 0, PATH_MAX + 1); memset(lost_found_dir, 0, PATH_MAX + 1); memset(frag_rank, 0, sizeof(struct frag_statistic_ino) * SHOW_FRAG_FILES); @@ -1921,6 +1768,7 @@ int main(int argc, char *argv[]) if (S_ISBLK(buf.st_mode)) { /* Block device */ + strncpy(dev_name, argv[i], strnlen(argv[i], PATH_MAX)); if (get_mount_point(argv[i], dir_name, PATH_MAX) < 0) continue; if (lstat64(dir_name, &buf) < 0) { @@ -1957,7 +1805,7 @@ int main(int argc, char *argv[]) * filesystem type checked in get_mount_point() */ if (arg_type == FILENAME || arg_type == DIRNAME) { - if (is_ext4(argv[i]) < 0) + if (is_ext4(argv[i], dev_name) < 0) continue; if (realpath(argv[i], dir_name) == NULL) { perror("Couldn't get full path"); @@ -1968,8 +1816,9 @@ int main(int argc, char *argv[]) if (current_uid == ROOT_UID) { /* Get super block info */ - memset(&sb, 0, sizeof(struct ext4_super_block)); - if (get_superblock_info(dir_name, &sb) < 0) { + ret = ext2fs_open(dev_name, 0, 0, block_size, + unix_io_manager, &fs); + if (ret) { if (mode_flag & DETAIL) { perror("Can't get super block info"); PRINT_FILE_NAME(argv[i]); @@ -1977,9 +1826,11 @@ int main(int argc, char *argv[]) continue; } - blocks_per_group = ext2fs_swab32(sb.s_blocks_per_group); - feature_incompat = ext2fs_swab32(sb.s_feature_incompat); - log_groups_per_flex = sb.s_log_groups_per_flex; + blocks_per_group = fs->super->s_blocks_per_group; + feature_incompat = fs->super->s_feature_incompat; + log_groups_per_flex = fs->super->s_log_groups_per_flex; + + ext2fs_close(fs); } switch (arg_type) { |