📄 tune2fs.c
字号:
/* vi: set sw=4 ts=4: *//* * tune2fs.c - Change the file system parameters on an ext2 file system * * Copyright (C) 1992, 1993, 1994 Remy Card <card@masi.ibp.fr> * Laboratoire MASI, Institut Blaise Pascal * Universite Pierre et Marie Curie (Paris VI) * * Copyright 1995, 1996, 1997, 1998, 1999, 2000 by Theodore Ts'o. * * %Begin-Header% * This file may be redistributed under the terms of the GNU Public * License. * %End-Header% *//* * History: * 93/06/01 - Creation * 93/10/31 - Added the -c option to change the maximal mount counts * 93/12/14 - Added -l flag to list contents of superblock * M.J.E. Mol (marcel@duteca.et.tudelft.nl) * F.W. ten Wolde (franky@duteca.et.tudelft.nl) * 93/12/29 - Added the -e option to change errors behavior * 94/02/27 - Ported to use the ext2fs library * 94/03/06 - Added the checks interval from Uwe Ohse (uwe@tirka.gun.de) */#include <sys/types.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <unistd.h>#include <getopt.h>#include "e2fsbb.h"#include "ext2fs/ext2_fs.h"#include "ext2fs/ext2fs.h"#include "uuid/uuid.h"#include "e2p/e2p.h"#include "ext2fs/kernel-jbd.h"#include "util.h"#include "blkid/blkid.h"#include "libbb.h"static char * device_name = NULL;static char * new_label, *new_last_mounted, *new_UUID;static char * io_options;static int c_flag, C_flag, e_flag, f_flag, g_flag, i_flag, l_flag, L_flag;static int m_flag, M_flag, r_flag, s_flag = -1, u_flag, U_flag, T_flag;static time_t last_check_time;static int print_label;static int max_mount_count, mount_count, mount_flags;static unsigned long interval, reserved_blocks;static unsigned reserved_ratio;static unsigned long resgid, resuid;static unsigned short errors;static int open_flag;static char *features_cmd;static char *mntopts_cmd;static int journal_size, journal_flags;static char *journal_device = NULL;static const char *please_fsck = "Please run e2fsck on the filesystem\n";static __u32 ok_features[3] = { EXT3_FEATURE_COMPAT_HAS_JOURNAL | EXT2_FEATURE_COMPAT_DIR_INDEX, EXT2_FEATURE_INCOMPAT_FILETYPE, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER};/* * Remove an external journal from the filesystem */static void remove_journal_device(ext2_filsys fs){ char *journal_path; ext2_filsys jfs; char buf[1024]; journal_superblock_t *jsb; int i, nr_users; errcode_t retval; int commit_remove_journal = 0; io_manager io_ptr; if (f_flag) commit_remove_journal = 1; /* force removal even if error */ uuid_unparse(fs->super->s_journal_uuid, buf); journal_path = blkid_get_devname(NULL, "UUID", buf); if (!journal_path) { journal_path = ext2fs_find_block_device(fs->super->s_journal_dev); if (!journal_path) return; } io_ptr = unix_io_manager; retval = ext2fs_open(journal_path, EXT2_FLAG_RW| EXT2_FLAG_JOURNAL_DEV_OK, 0, fs->blocksize, io_ptr, &jfs); if (retval) { bb_error_msg("Failed to open external journal"); goto no_valid_journal; } if (!(jfs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) { bb_error_msg("%s is not a journal device", journal_path); goto no_valid_journal; } /* Get the journal superblock */ if ((retval = io_channel_read_blk(jfs->io, 1, -1024, buf))) { bb_error_msg("Failed to read journal superblock"); goto no_valid_journal; } jsb = (journal_superblock_t *) buf; if ((jsb->s_header.h_magic != (unsigned) ntohl(JFS_MAGIC_NUMBER)) || (jsb->s_header.h_blocktype != (unsigned) ntohl(JFS_SUPERBLOCK_V2))) { bb_error_msg("Journal superblock not found!"); goto no_valid_journal; } /* Find the filesystem UUID */ nr_users = ntohl(jsb->s_nr_users); for (i=0; i < nr_users; i++) { if (memcmp(fs->super->s_uuid, &jsb->s_users[i*16], 16) == 0) break; } if (i >= nr_users) { bb_error_msg("Filesystem's UUID not found on journal device"); commit_remove_journal = 1; goto no_valid_journal; } nr_users--; for (i=0; i < nr_users; i++) memcpy(&jsb->s_users[i*16], &jsb->s_users[(i+1)*16], 16); jsb->s_nr_users = htonl(nr_users); /* Write back the journal superblock */ if ((retval = io_channel_write_blk(jfs->io, 1, -1024, buf))) { bb_error_msg("Failed to write journal superblock"); goto no_valid_journal; } commit_remove_journal = 1;no_valid_journal: if (commit_remove_journal == 0) bb_error_msg_and_die("Journal NOT removed"); fs->super->s_journal_dev = 0; uuid_clear(fs->super->s_journal_uuid); ext2fs_mark_super_dirty(fs); puts("Journal removed"); free(journal_path);}/* Helper function for remove_journal_inode */static int release_blocks_proc(ext2_filsys fs, blk_t *blocknr, int blockcnt EXT2FS_ATTR((unused)), void *private EXT2FS_ATTR((unused))){ blk_t block; int group; block = *blocknr; ext2fs_unmark_block_bitmap(fs->block_map,block); group = ext2fs_group_of_blk(fs, block); fs->group_desc[group].bg_free_blocks_count++; fs->super->s_free_blocks_count++; return 0;}/* * Remove the journal inode from the filesystem */static void remove_journal_inode(ext2_filsys fs){ struct ext2_inode inode; errcode_t retval; ino_t ino = fs->super->s_journal_inum; char *msg = "to read"; char *s = "journal inode"; retval = ext2fs_read_inode(fs, ino, &inode); if (retval) goto REMOVE_JOURNAL_INODE_ERROR; if (ino == EXT2_JOURNAL_INO) { retval = ext2fs_read_bitmaps(fs); if (retval) { msg = "to read bitmaps"; s = ""; goto REMOVE_JOURNAL_INODE_ERROR; } retval = ext2fs_block_iterate(fs, ino, 0, NULL, release_blocks_proc, NULL); if (retval) { msg = "clearing"; goto REMOVE_JOURNAL_INODE_ERROR; } memset(&inode, 0, sizeof(inode)); ext2fs_mark_bb_dirty(fs); fs->flags &= ~EXT2_FLAG_SUPER_ONLY; } else inode.i_flags &= ~EXT2_IMMUTABLE_FL; retval = ext2fs_write_inode(fs, ino, &inode); if (retval) { msg = "writing";REMOVE_JOURNAL_INODE_ERROR: bb_error_msg_and_die("Failed %s %s", msg, s); } fs->super->s_journal_inum = 0; ext2fs_mark_super_dirty(fs);}/* * Update the default mount options */static void update_mntopts(ext2_filsys fs, char *mntopts){ struct ext2_super_block *sb= fs->super; if (e2p_edit_mntopts(mntopts, &sb->s_default_mount_opts, ~0)) bb_error_msg_and_die("Invalid mount option set: %s", mntopts); ext2fs_mark_super_dirty(fs);}/* * Update the feature set as provided by the user. */static void update_feature_set(ext2_filsys fs, char *features){ int sparse, old_sparse, filetype, old_filetype; int journal, old_journal, dxdir, old_dxdir; struct ext2_super_block *sb= fs->super; __u32 old_compat, old_incompat, old_ro_compat; old_compat = sb->s_feature_compat; old_ro_compat = sb->s_feature_ro_compat; old_incompat = sb->s_feature_incompat; old_sparse = sb->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; old_filetype = sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE; old_journal = sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL; old_dxdir = sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX; if (e2p_edit_feature(features, &sb->s_feature_compat, ok_features)) bb_error_msg_and_die("Invalid filesystem option set: %s", features); sparse = sb->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; filetype = sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE; journal = sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL; dxdir = sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX; if (old_journal && !journal) { if ((mount_flags & EXT2_MF_MOUNTED) && !(mount_flags & EXT2_MF_READONLY)) { bb_error_msg_and_die( "The has_journal flag may only be " "cleared when the filesystem is\n" "unmounted or mounted " "read-only"); } if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) { bb_error_msg_and_die( "The needs_recovery flag is set. " "%s before clearing the has_journal flag.", please_fsck); } if (sb->s_journal_inum) { remove_journal_inode(fs); } if (sb->s_journal_dev) { remove_journal_device(fs); } } if (journal && !old_journal) { /* * If adding a journal flag, let the create journal * code below handle creating setting the flag and * creating the journal. We supply a default size if * necessary. */ if (!journal_size) journal_size = -1; sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL; } if (dxdir && !old_dxdir) { if (!sb->s_def_hash_version) sb->s_def_hash_version = EXT2_HASH_TEA; if (uuid_is_null((unsigned char *) sb->s_hash_seed)) uuid_generate((unsigned char *) sb->s_hash_seed); } if (sb->s_rev_level == EXT2_GOOD_OLD_REV && (sb->s_feature_compat || sb->s_feature_ro_compat || sb->s_feature_incompat)) ext2fs_update_dynamic_rev(fs); if ((sparse != old_sparse) || (filetype != old_filetype)) { sb->s_state &= ~EXT2_VALID_FS; printf("\n%s\n", please_fsck); } if ((old_compat != sb->s_feature_compat) || (old_ro_compat != sb->s_feature_ro_compat) || (old_incompat != sb->s_feature_incompat)) ext2fs_mark_super_dirty(fs);}/* * Add a journal to the filesystem. */static void add_journal(ext2_filsys fs){ if (fs->super->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) { bb_error_msg_and_die("The filesystem already has a journal"); } if (journal_device) { make_journal_device(journal_device, fs, 0, 0); } else if (journal_size) { make_journal_blocks(fs, journal_size, journal_flags, 0); /* * If the filesystem wasn't mounted, we need to force * the block group descriptors out. */ if ((mount_flags & EXT2_MF_MOUNTED) == 0) fs->flags &= ~EXT2_FLAG_SUPER_ONLY; } print_check_message(fs);}/* * Busybox stuff */static char * x_blkid_get_devname(const char *token){ char * dev_name; if (!(dev_name = blkid_get_devname(NULL, token, NULL))) bb_error_msg_and_die("Unable to resolve '%s'", token); return dev_name;}#ifdef CONFIG_E2LABELstatic void parse_e2label_options(int argc, char ** argv){ if ((argc < 2) || (argc > 3)) bb_show_usage(); io_options = strchr(argv[1], '?'); if (io_options) *io_options++ = 0; device_name = x_blkid_get_devname(argv[1]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -