tune2fs.c revision 65f0aab98b20b5994a726ab90d355248bcddfffd
1d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim/* 2d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim * tune2fs.c - Change the file system parameters on an ext2 file system 3d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim * 4d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim * Copyright (C) 1992, 1993, 1994 Remy Card <card@masi.ibp.fr> 5d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim * Laboratoire MASI, Institut Blaise Pascal 6d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim * Universite Pierre et Marie Curie (Paris VI) 7d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim * 8d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim * Copyright 1995, 1996, 1997, 1998, 1999, 2000 by Theodore Ts'o. 9d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim * 10d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach * %Begin-Header% 11d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth * This file may be redistributed under the terms of the GNU Public 12be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng * License. 13be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng * %End-Header% 1419d54337169ae4af2d44ae39664d0bac1ae0309cQuentin Colombet */ 15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth 16d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim/* 177a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach * History: 185be6d2af38c29e3653998978345220974cc40c01Jim Grosbach * 93/06/01 - Creation 19285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola * 93/10/31 - Added the -c option to change the maximal mount counts 20d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim * 93/12/14 - Added -l flag to list contents of superblock 21f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper * M.J.E. Mol (marcel@duteca.et.tudelft.nl) 22aa4b7dd13ba83152473950d7014a29686dc7eef6Daniel Dunbar * F.W. ten Wolde (franky@duteca.et.tudelft.nl) 23d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim * 93/12/29 - Added the -e option to change errors behavior 24d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim * 94/02/27 - Ported to use the ext2fs library 25d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim * 94/03/06 - Added the checks interval from Uwe Ohse (uwe@tirka.gun.de) 26d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach */ 279b5b125c34b47e0e7eef2548acee8bf1448c4b71Jim Grosbach 28eecb858ca86fa949c06f819d6127e2ac68d165c8Wesley Peck#define _XOPEN_SOURCE 600 /* for inclusion of strptime() */ 29d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim#define _BSD_SOURCE /* for inclusion of strcasecmp() */ 305510728d28bb1ee04abc32da3d21b7df12948053Charles Davis#include <fcntl.h> 31d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim#include <grp.h> 32d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim#ifdef HAVE_GETOPT_H 33d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim#include <getopt.h> 34d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim#else 356024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindolaextern char *optarg; 366024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindolaextern int optind; 37dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola#endif 38dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola#include <pwd.h> 39bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola#include <stdio.h> 406024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola#ifdef HAVE_STDLIB_H 416024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola#include <stdlib.h> 4278c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng#endif 43d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach#include <string.h> 4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include <time.h> 4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include <unistd.h> 46d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim#include <sys/types.h> 4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include <libgen.h> 48d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach#include <limits.h> 4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 50d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach#include "ext2fs/ext2_fs.h" 51d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach#include "ext2fs/ext2fs.h" 52d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach#include "et/com_err.h" 53d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach#include "uuid/uuid.h" 54d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim#include "e2p/e2p.h" 5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "jfs_user.h" 5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "util.h" 5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "blkid/blkid.h" 582761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar 59d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach#include "../version.h" 60d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach#include "nls-enable.h" 61d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach 62d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbachconst char *program_name = "tune2fs"; 6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineschar *device_name; 6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineschar *new_label, *new_last_mounted, *new_UUID; 652761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbarchar *io_options; 662761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbarstatic int c_flag, C_flag, e_flag, f_flag, g_flag, i_flag, l_flag, L_flag; 672761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbarstatic int m_flag, M_flag, r_flag, s_flag = -1, u_flag, U_flag, T_flag; 682761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbarstatic int I_flag; 692abba8496cb394af53b531e95067d5cae78bb9eeJim Grosbachstatic time_t last_check_time; 702761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbarstatic int print_label; 712761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbarstatic int max_mount_count, mount_count, mount_flags; 722f196747f15240691bd4e622f7995edfedf90f61Jim Grosbachstatic unsigned long interval, reserved_blocks; 73681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbachstatic double reserved_ratio; 742761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbarstatic unsigned long resgid, resuid; 752761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbarstatic unsigned short errors; 762761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbarstatic int open_flag; 772761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbarstatic char *features_cmd; 782abba8496cb394af53b531e95067d5cae78bb9eeJim Grosbachstatic char *mntopts_cmd; 792761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbarstatic int stride, stripe_width; 802761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbarstatic int stride_set, stripe_width_set; 81685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kimstatic char *extended_cmd; 82685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kimstatic unsigned long new_inode_size; 832761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar 842761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbarint journal_size, journal_flags; 852761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbarchar *journal_device; 86cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy 87cb0809b82b126e79b99755ae4fc3d9733faea038James Molloystatic struct list_head blk_move_list; 887b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach 892761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbarstruct blk_move { 9090b5a08e1ffc4a1c18f7fa964ca561fa4b03c314Jim Grosbach struct list_head list; 912761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar blk_t old_loc; 929da7892fbe1c9e7c592c5928e36724a0e190a777Jim Grosbach blk_t new_loc; 939da7892fbe1c9e7c592c5928e36724a0e190a777Jim Grosbach}; 94fea51fc007598176d48fb7319a9bf471efb93127Eric Christopher 95f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng 96f3eb3bba1614a7935b44fc963a805088d71267f3Evan Chengstatic const char *please_fsck = N_("Please run e2fsck on the filesystem.\n"); 97f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng 98f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng#ifdef CONFIG_BUILD_FINDFS 99f3eb3bba1614a7935b44fc963a805088d71267f3Evan Chengvoid do_findfs(int argc, char **argv); 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif 10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic void usage(void) 10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines{ 10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines fprintf(stderr, 10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines _("Usage: %s [-c max_mounts_count] [-e errors_behavior] " 10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "[-g group]\n" 10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "\t[-i interval[d|m|w]] [-j] [-J journal_options] [-l]\n" 10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "\t[-m reserved_blocks_percent] " 10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "[-o [^]mount_options[,...]] \n" 11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "\t[-r reserved_blocks_count] [-u user] [-C mount_count] " 11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "[-L volume_label]\n" 11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "\t[-M last_mounted_dir] [-O [^]feature[,...]]\n" 11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "\t[-E extended-option[,...]] [-T last_check_time] " 11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "[-U UUID]\n\t[ -I new_inode_size ] device\n"), program_name); 11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines exit(1); 11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic __u32 ok_features[3] = { 11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /* Compat */ 12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT3_FEATURE_COMPAT_HAS_JOURNAL | 12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT2_FEATURE_COMPAT_DIR_INDEX, 12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /* Incompat */ 12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT2_FEATURE_INCOMPAT_FILETYPE | 12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT3_FEATURE_INCOMPAT_EXTENTS | 12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT4_FEATURE_INCOMPAT_FLEX_BG, 12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /* R/O compat */ 12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT2_FEATURE_RO_COMPAT_LARGE_FILE | 12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT4_FEATURE_RO_COMPAT_HUGE_FILE| 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT4_FEATURE_RO_COMPAT_DIR_NLINK| 13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE| 13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT4_FEATURE_RO_COMPAT_GDT_CSUM | 13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic __u32 clear_ok_features[3] = { 13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /* Compat */ 1372761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar EXT3_FEATURE_COMPAT_HAS_JOURNAL | 1382761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar EXT2_FEATURE_COMPAT_RESIZE_INODE | 1392761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar EXT2_FEATURE_COMPAT_DIR_INDEX, 14078c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng /* Incompat */ 1412761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar EXT2_FEATURE_INCOMPAT_FILETYPE | 1422761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar EXT4_FEATURE_INCOMPAT_FLEX_BG, 1432761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar /* R/O compat */ 14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT2_FEATURE_RO_COMPAT_LARGE_FILE | 1452761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar EXT4_FEATURE_RO_COMPAT_HUGE_FILE| 1462761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar EXT4_FEATURE_RO_COMPAT_DIR_NLINK| 1479b5b125c34b47e0e7eef2548acee8bf1448c4b71Jim Grosbach EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE| 1489b5b125c34b47e0e7eef2548acee8bf1448c4b71Jim Grosbach EXT4_FEATURE_RO_COMPAT_GDT_CSUM 1499b5b125c34b47e0e7eef2548acee8bf1448c4b71Jim Grosbach}; 1509b5b125c34b47e0e7eef2548acee8bf1448c4b71Jim Grosbach 15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/* 15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Remove an external journal from the filesystem 1539b5b125c34b47e0e7eef2548acee8bf1448c4b71Jim Grosbach */ 154cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramerstatic void remove_journal_device(ext2_filsys fs) 155cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer{ 15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines char *journal_path; 157cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer ext2_filsys jfs; 15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines char buf[1024]; 159d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim journal_superblock_t *jsb; 16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int i, nr_users; 161251040bc18eedfa56d01fe92836e55cfd8c5d990Eli Bendersky errcode_t retval; 16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int commit_remove_journal = 0; 163370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach io_manager io_ptr; 16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 165d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim if (f_flag) 16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines commit_remove_journal = 1; /* force removal even if error */ 1673787a40e038d6444a1b0e93f1cdc55fb006a5392Jim Grosbach 16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uuid_unparse(fs->super->s_journal_uuid, buf); 1695be6d2af38c29e3653998978345220974cc40c01Jim Grosbach journal_path = blkid_get_devname(NULL, "UUID", buf); 1705be6d2af38c29e3653998978345220974cc40c01Jim Grosbach 1715be6d2af38c29e3653998978345220974cc40c01Jim Grosbach if (!journal_path) { 1725be6d2af38c29e3653998978345220974cc40c01Jim Grosbach journal_path = 1735be6d2af38c29e3653998978345220974cc40c01Jim Grosbach ext2fs_find_block_device(fs->super->s_journal_dev); 1745be6d2af38c29e3653998978345220974cc40c01Jim Grosbach if (!journal_path) 1755be6d2af38c29e3653998978345220974cc40c01Jim Grosbach return; 1765be6d2af38c29e3653998978345220974cc40c01Jim Grosbach } 1775be6d2af38c29e3653998978345220974cc40c01Jim Grosbach 1783787a40e038d6444a1b0e93f1cdc55fb006a5392Jim Grosbach#ifdef CONFIG_TESTIO_DEBUG 1795be6d2af38c29e3653998978345220974cc40c01Jim Grosbach if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) { 1805be6d2af38c29e3653998978345220974cc40c01Jim Grosbach io_ptr = test_io_manager; 1815be6d2af38c29e3653998978345220974cc40c01Jim Grosbach test_io_backing_manager = unix_io_manager; 1825be6d2af38c29e3653998978345220974cc40c01Jim Grosbach } else 18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif 184d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim io_ptr = unix_io_manager; 185b75c651e22a63907b727664f044283bf9c9fb885Chris Lattner retval = ext2fs_open(journal_path, EXT2_FLAG_RW| 186d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim EXT2_FLAG_JOURNAL_DEV_OK, 0, 187f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach fs->blocksize, io_ptr, &jfs); 188f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach if (retval) { 189f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach com_err(program_name, retval, 190256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach _("while trying to open external journal")); 19102265382929b0275d7b7b334eab5e2fd34e1b9feMihai Popa goto no_valid_journal; 1929363c58dc2473a6470d3e7037afe8a215bee7e3eJim Grosbach } 193fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach if (!(jfs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) { 19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines fprintf(stderr, _("%s is not a journal device.\n"), 19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines journal_path); 196f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach goto no_valid_journal; 197f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach } 198f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach 199ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach /* Get the journal superblock */ 200f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach if ((retval = io_channel_read_blk(jfs->io, 1, -1024, buf))) { 201f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach com_err(program_name, retval, 202d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim _("while reading journal superblock")); 203d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim goto no_valid_journal; 204d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim } 205370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach 206370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach jsb = (journal_superblock_t *) buf; 207251040bc18eedfa56d01fe92836e55cfd8c5d990Eli Bendersky if ((jsb->s_header.h_magic != (unsigned) ntohl(JFS_MAGIC_NUMBER)) || 208370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach (jsb->s_header.h_blocktype != (unsigned) ntohl(JFS_SUPERBLOCK_V2))) { 209e545ee20f1b6ea6c03919cc9bc1a4a059c2f03b6Benjamin Kramer fputs(_("Journal superblock not found!\n"), stderr); 210fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach goto no_valid_journal; 211fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach } 212fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach 213fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach /* Find the filesystem UUID */ 214fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach nr_users = ntohl(jsb->s_nr_users); 215fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach for (i = 0; i < nr_users; i++) { 216fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach if (memcmp(fs->super->s_uuid, 217fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach &jsb->s_users[i*16], 16) == 0) 218fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach break; 219fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach } 220256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach if (i >= nr_users) { 221256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach fputs(_("Filesystem's UUID not found on journal device.\n"), 222256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach stderr); 223256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach commit_remove_journal = 1; 224256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach goto no_valid_journal; 225256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach } 226256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach nr_users--; 227256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach for (i = 0; i < nr_users; i++) 228256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach memcpy(&jsb->s_users[i*16], &jsb->s_users[(i+1)*16], 16); 229256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach jsb->s_nr_users = htonl(nr_users); 2309363c58dc2473a6470d3e7037afe8a215bee7e3eJim Grosbach 231256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach /* Write back the journal superblock */ 232d26bad079d6977309699e0bc9203451904acbd86Jim Grosbach if ((retval = io_channel_write_blk(jfs->io, 1, -1024, buf))) { 233d26bad079d6977309699e0bc9203451904acbd86Jim Grosbach com_err(program_name, retval, 234256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach "while writing journal superblock."); 235d26bad079d6977309699e0bc9203451904acbd86Jim Grosbach goto no_valid_journal; 236256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach } 23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines commit_remove_journal = 1; 23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesno_valid_journal: 24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (commit_remove_journal == 0) { 24236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines fputs(_("Journal NOT removed\n"), stderr); 243256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach exit(1); 244e545ee20f1b6ea6c03919cc9bc1a4a059c2f03b6Benjamin Kramer } 245370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach fs->super->s_journal_dev = 0; 246370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach uuid_clear(fs->super->s_journal_uuid); 247ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach ext2fs_mark_super_dirty(fs); 248f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach fputs(_("Journal removed\n"), stdout); 249f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach free(journal_path); 250f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach} 251f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach 252f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach/* Helper function for remove_journal_inode */ 253f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbachstatic int release_blocks_proc(ext2_filsys fs, blk_t *blocknr, 254f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach int blockcnt EXT2FS_ATTR((unused)), 255f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach void *private EXT2FS_ATTR((unused))) 256f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach{ 257f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach blk_t block; 258f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach int group; 25936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines block = *blocknr; 26136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ext2fs_unmark_block_bitmap(fs->block_map, block); 26236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines group = ext2fs_group_of_blk(fs, block); 26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines fs->group_desc[group].bg_free_blocks_count++; 26436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ext2fs_group_desc_csum_set(fs, group); 26536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines fs->super->s_free_blocks_count++; 26636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 0; 26736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 26836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 26936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/* 27036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Remove the journal inode from the filesystem 271f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach */ 272f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbachstatic void remove_journal_inode(ext2_filsys fs) 273f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach{ 274d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim struct ext2_inode inode; 275d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim errcode_t retval; 276ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach ino_t ino = fs->super->s_journal_inum; 277d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach 278d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach retval = ext2fs_read_inode(fs, ino, &inode); 279f2a1c83c86ceefb9a241aa728d1d1239a64b894eDavid Sehr if (retval) { 280b84acd24687c721e3da46bb56a94d393bc5a8cbcJim Grosbach com_err(program_name, retval, 2815be6d2af38c29e3653998978345220974cc40c01Jim Grosbach _("while reading journal inode")); 282d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach exit(1); 283d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach } 284a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach if (ino == EXT2_JOURNAL_INO) { 285a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach retval = ext2fs_read_bitmaps(fs); 286d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach if (retval) { 287a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach com_err(program_name, retval, 288a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach _("while reading bitmaps")); 2895be6d2af38c29e3653998978345220974cc40c01Jim Grosbach exit(1); 2905be6d2af38c29e3653998978345220974cc40c01Jim Grosbach } 2915be6d2af38c29e3653998978345220974cc40c01Jim Grosbach retval = ext2fs_block_iterate(fs, ino, 292d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach BLOCK_FLAG_READ_ONLY, NULL, 293d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach release_blocks_proc, NULL); 294a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach if (retval) { 295a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach com_err(program_name, retval, 296d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach _("while clearing journal inode")); 297d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach exit(1); 298d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach } 299a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach memset(&inode, 0, sizeof(inode)); 300a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach ext2fs_mark_bb_dirty(fs); 301a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach fs->flags &= ~EXT2_FLAG_SUPER_ONLY; 302a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach } else 303a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach inode.i_flags &= ~EXT2_IMMUTABLE_FL; 304a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach retval = ext2fs_write_inode(fs, ino, &inode); 305a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach if (retval) { 306cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola com_err(program_name, retval, 30787dc3aa2d87871f1affc6f3f2fa587c7b6725d83Jim Grosbach _("while writing journal inode")); 308d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim exit(1); 309dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 310dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines fs->super->s_journal_inum = 0; 311dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ext2fs_mark_super_dirty(fs); 312dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 313dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 314dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/* 315dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines * Update the default mount options 316dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines */ 317dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic void update_mntopts(ext2_filsys fs, char *mntopts) 318dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines{ 319dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines struct ext2_super_block *sb = fs->super; 320dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 321dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (e2p_edit_mntopts(mntopts, &sb->s_default_mount_opts, ~0)) { 322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines fprintf(stderr, _("Invalid mount option set: %s\n"), 323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines mntopts); 324dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines exit(1); 325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 326dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ext2fs_mark_super_dirty(fs); 327dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 328dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 329dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic void request_fsck_afterwards(ext2_filsys fs) 330dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines{ 331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines static int requested = 0; 332dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 333dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (requested++) 334dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return; 335dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines fs->super->s_state &= ~EXT2_VALID_FS; 3367a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach printf("\n%s\n", _(please_fsck)); 337dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (mount_flags & EXT2_MF_READONLY) 338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines printf(_("(and reboot afterwards!)\n")); 3397a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach} 3400c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim 3410c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim/* 3420c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim * Update the feature set as provided by the user. 3436ec6eeb692fa11b569af8b69b2bb11cc84f04926Jim Grosbach */ 3446ec6eeb692fa11b569af8b69b2bb11cc84f04926Jim Grosbachstatic void update_feature_set(ext2_filsys fs, char *features) 3450c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim{ 3462ccf148fbaaf9ea15233d7ef09e31ca0fa6ee3beJason W Kim struct ext2_super_block *sb = fs->super; 347dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines struct ext2_group_desc *gd; 348dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines errcode_t retval; 349dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines __u32 old_features[3]; 350dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines int i, type_err; 3510c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim unsigned int mask_err; 35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define FEATURE_ON(type, mask) (!(old_features[(type)] & (mask)) && \ 354f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng ((&sb->s_feature_compat)[(type)] & (mask))) 35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define FEATURE_OFF(type, mask) ((old_features[(type)] & (mask)) && \ 3562ccf148fbaaf9ea15233d7ef09e31ca0fa6ee3beJason W Kim !((&sb->s_feature_compat)[(type)] & (mask))) 3572ccf148fbaaf9ea15233d7ef09e31ca0fa6ee3beJason W Kim#define FEATURE_CHANGED(type, mask) ((mask) & \ 3582ccf148fbaaf9ea15233d7ef09e31ca0fa6ee3beJason W Kim (old_features[(type)] ^ (&sb->s_feature_compat)[(type)])) 3592ccf148fbaaf9ea15233d7ef09e31ca0fa6ee3beJason W Kim 3602ccf148fbaaf9ea15233d7ef09e31ca0fa6ee3beJason W Kim old_features[E2P_FEATURE_COMPAT] = sb->s_feature_compat; 3610c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim old_features[E2P_FEATURE_INCOMPAT] = sb->s_feature_incompat; 3622ccf148fbaaf9ea15233d7ef09e31ca0fa6ee3beJason W Kim old_features[E2P_FEATURE_RO_INCOMPAT] = sb->s_feature_ro_compat; 363f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng 36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (e2p_edit_feature2(features, &sb->s_feature_compat, 36536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ok_features, clear_ok_features, 366f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng &type_err, &mask_err)) { 36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!mask_err) 368f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng fprintf(stderr, 369f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng _("Invalid filesystem option set: %s\n"), 370f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng features); 371f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng else if (type_err & E2P_FEATURE_NEGATE_FLAG) 372f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng fprintf(stderr, _("Clearing filesystem feature '%s' " 373f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng "not supported.\n"), 374f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng e2p_feature2string(type_err & 375f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng E2P_FEATURE_TYPE_MASK, 376f391e9f696183a8dfb6b0d1e791687a520552f85Jim Grosbach mask_err)); 377dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else 378f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng fprintf(stderr, _("Setting filesystem feature '%s' " 379d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson "not supported.\n"), 3800c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim e2p_feature2string(type_err, mask_err)); 38105018c2f2872a05b1a2fff1a9934621ba1f38084Owen Anderson exit(1); 382fe7fac74b4edaf9cc04460fc21aa949e5533aea2Owen Anderson } 383d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson 384d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson if (FEATURE_OFF(E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) { 38505018c2f2872a05b1a2fff1a9934621ba1f38084Owen Anderson if ((mount_flags & EXT2_MF_MOUNTED) && 386d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson !(mount_flags & EXT2_MF_READONLY)) { 3870c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim fputs(_("The has_journal feature may only be " 3880c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim "cleared when the filesystem is\n" 3890c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim "unmounted or mounted " 3900c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim "read-only.\n"), stderr); 3917a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach exit(1); 3927a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach } 3930c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim if (sb->s_feature_incompat & 3947e294cfcf97cd7b94bf5c4de0f214480ec13adadJim Grosbach EXT3_FEATURE_INCOMPAT_RECOVER) { 395d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson fputs(_("The needs_recovery flag is set. " 396d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson "Please run e2fsck before clearing\n" 397dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "the has_journal flag.\n"), stderr); 398dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines exit(1); 3997e294cfcf97cd7b94bf5c4de0f214480ec13adadJim Grosbach } 4000c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim if (sb->s_journal_inum) { 4010c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim remove_journal_inode(fs); 402d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach } 403d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach if (sb->s_journal_dev) { 404dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach remove_journal_device(fs); 405dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach } 406dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach } 407dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach 408dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach if (FEATURE_ON(E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) { 409dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach /* 410dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach * If adding a journal flag, let the create journal 411dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach * code below handle setting the flag and creating the 4127a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach * journal. We supply a default size if necessary. 4137a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach */ 414dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach if (!journal_size) 415dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach journal_size = -1; 416dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL; 417e8eb1ea6acd54538b42491b95d8fc6281d4b5710Jim Grosbach } 418a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson 419a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson if (FEATURE_ON(E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_INDEX)) { 420a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson if (!sb->s_def_hash_version) 421a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson sb->s_def_hash_version = EXT2_HASH_HALF_MD4; 422a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson if (uuid_is_null((unsigned char *) sb->s_hash_seed)) 423a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson uuid_generate((unsigned char *) sb->s_hash_seed); 424a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson } 425a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson 426a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson if (FEATURE_OFF(E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_FLEX_BG)) { 427741ad15e26d1717433f326743800f30c63c6a9c1Owen Anderson if (ext2fs_check_desc(fs)) { 428a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson fputs(_("Clearing the flex_bg flag would " 429a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson "cause the the filesystem to be\n" 430e8eb1ea6acd54538b42491b95d8fc6281d4b5710Jim Grosbach "inconsistent.\n"), stderr); 431dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines exit(1); 432a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson } 433e8eb1ea6acd54538b42491b95d8fc6281d4b5710Jim Grosbach } 434685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim 435685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim if (FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT, 436cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) { 437cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy if ((mount_flags & EXT2_MF_MOUNTED) && 4387b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach !(mount_flags & EXT2_MF_READONLY)) { 4390c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim fputs(_("The huge_file feature may only be " 4400c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim "cleared when the filesystem is\n" 44136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "unmounted or mounted " 44236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "read-only.\n"), stderr); 44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines exit(1); 444662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach } 445c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson } 44663ee22065dc4e8af7f4bf99c25b82da132700267Owen Anderson 447fb20d890756b75d6ccfa7ab17f170a877d425dc6Owen Anderson if (FEATURE_ON(E2P_FEATURE_RO_INCOMPAT, 4487e294cfcf97cd7b94bf5c4de0f214480ec13adadJim Grosbach EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) { 44956a2535474dd4482c432b3c75c3dab4b2f3dd1e2Jim Grosbach gd = fs->group_desc; 450c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson for (i = 0; i < fs->group_desc_count; i++, gd++) { 451c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson gd->bg_itable_unused = 0; 452c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson gd->bg_flags = EXT2_BG_INODE_ZEROED; 453c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson ext2fs_group_desc_csum_set(fs, i); 454c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson } 455e8eb1ea6acd54538b42491b95d8fc6281d4b5710Jim Grosbach fs->flags &= ~EXT2_FLAG_SUPER_ONLY; 456c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson } 457c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson 458c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson if (FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT, 459c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) { 460c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson gd = fs->group_desc; 461e8eb1ea6acd54538b42491b95d8fc6281d4b5710Jim Grosbach for (i = 0; i < fs->group_desc_count; i++, gd++) { 462dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if ((gd->bg_flags & EXT2_BG_INODE_ZEROED) == 0) { 463c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson /* 464c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson * XXX what we really should do is zap 465c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson * uninitialized inode tables instead. 466c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson */ 467e8eb1ea6acd54538b42491b95d8fc6281d4b5710Jim Grosbach request_fsck_afterwards(fs); 468c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson break; 4698f0794331765661f92cf074f638acb1ea927bb5dOwen Anderson } 4708f0794331765661f92cf074f638acb1ea927bb5dOwen Anderson gd->bg_itable_unused = 0; 4718f0794331765661f92cf074f638acb1ea927bb5dOwen Anderson gd->bg_flags = 0; 4728f0794331765661f92cf074f638acb1ea927bb5dOwen Anderson gd->bg_checksum = 0; 4738f0794331765661f92cf074f638acb1ea927bb5dOwen Anderson } 4747e294cfcf97cd7b94bf5c4de0f214480ec13adadJim Grosbach fs->flags &= ~EXT2_FLAG_SUPER_ONLY; 475dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 476fb20d890756b75d6ccfa7ab17f170a877d425dc6Owen Anderson 477662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach if (sb->s_rev_level == EXT2_GOOD_OLD_REV && 47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (sb->s_feature_compat || sb->s_feature_ro_compat || 47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines sb->s_feature_incompat)) 48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ext2fs_update_dynamic_rev(fs); 48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 48236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (FEATURE_CHANGED(E2P_FEATURE_RO_INCOMPAT, 48336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) || 48436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT, 48536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT4_FEATURE_RO_COMPAT_HUGE_FILE) || 48636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FEATURE_CHANGED(E2P_FEATURE_INCOMPAT, 48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT2_FEATURE_INCOMPAT_FILETYPE) || 48836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FEATURE_CHANGED(E2P_FEATURE_COMPAT, 48936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT2_FEATURE_COMPAT_RESIZE_INODE) || 49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT, 49136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) 49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines request_fsck_afterwards(fs); 49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((old_features[E2P_FEATURE_COMPAT] != sb->s_feature_compat) || 49536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (old_features[E2P_FEATURE_INCOMPAT] != sb->s_feature_incompat) || 49636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (old_features[E2P_FEATURE_RO_INCOMPAT] != sb->s_feature_ro_compat)) 49736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ext2fs_mark_super_dirty(fs); 49836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 499dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/* 50136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Add a journal to the filesystem. 502dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines */ 50309aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendlingstatic void add_journal(ext2_filsys fs) 50409aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling{ 50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned long journal_blocks; 50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines errcode_t retval; 50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ext2_filsys jfs; 50836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines io_manager io_ptr; 50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (fs->super->s_feature_compat & 51136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT3_FEATURE_COMPAT_HAS_JOURNAL) { 51236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines fputs(_("The filesystem already has a journal.\n"), stderr); 51336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines goto err; 51436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 51536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (journal_device) { 51636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines check_plausibility(journal_device); 51736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines check_mount(journal_device, 0, _("journal")); 51836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#ifdef CONFIG_TESTIO_DEBUG 51936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) { 52036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines io_ptr = test_io_manager; 52136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines test_io_backing_manager = unix_io_manager; 52236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else 52336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif 52436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines io_ptr = unix_io_manager; 52536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines retval = ext2fs_open(journal_device, EXT2_FLAG_RW| 52636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT2_FLAG_JOURNAL_DEV_OK, 0, 52736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines fs->blocksize, io_ptr, &jfs); 52836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (retval) { 529dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines com_err(program_name, retval, 530dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines _("\n\twhile trying to open journal on %s\n"), 53136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines journal_device); 532dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines goto err; 533662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach } 534b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling printf(_("Creating journal on device %s: "), 5350c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach journal_device); 5360c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach fflush(stdout); 5370c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach 5380c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach retval = ext2fs_add_journal_device(fs, jfs); 539b492a7c2134d3886f545f1b5ea55115d71529a10Jim Grosbach ext2fs_close(jfs); 540dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling if (retval) { 541dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling com_err(program_name, retval, 54286abd48fd01080f08eec1b46f92c90308b03bfd4Owen Anderson _("while adding filesystem to journal on %s"), 543dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling journal_device); 544e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach goto err; 545e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach } 546e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach fputs(_("done\n"), stdout); 54701086451393ef33e82b6fad623989dd97dd70edfJim Grosbach } else if (journal_size) { 54801086451393ef33e82b6fad623989dd97dd70edfJim Grosbach fputs(_("Creating journal inode: "), stdout); 54901086451393ef33e82b6fad623989dd97dd70edfJim Grosbach fflush(stdout); 5502f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach journal_blocks = figure_journal_size(journal_size, fs); 5512f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach 5522f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach retval = ext2fs_add_journal_inode(fs, journal_blocks, 5532f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach journal_flags); 5542f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach if (retval) { 5552f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach fprintf(stderr, "\n"); 5562f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach com_err(program_name, retval, 5572f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach _("\n\twhile trying to create journal file")); 558bf3c322640fdaf6e4a60a59ed8cb108a7f6685adJim Grosbach exit(1); 5597a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach } else 5607a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach fputs(_("done\n"), stdout); 561bf3c322640fdaf6e4a60a59ed8cb108a7f6685adJim Grosbach /* 5622f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach * If the filesystem wasn't mounted, we need to force 5632f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach * the block group descriptors out. 5640c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach */ 565e2e0f58809374265bd75edeefae8817e7ade62b4Owen Anderson if ((mount_flags & EXT2_MF_MOUNTED) == 0) 5660c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach fs->flags &= ~EXT2_FLAG_SUPER_ONLY; 5670c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach } 5680c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach print_check_message(fs); 5690c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach return; 570e2e0f58809374265bd75edeefae8817e7ade62b4Owen Anderson 5710c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kimerr: 5720c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim free(journal_device); 5730c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim exit(1); 5740c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim} 5750c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim 5760c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim 5770c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kimstatic void parse_e2label_options(int argc, char ** argv) 5787a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach{ 5797a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach if ((argc < 2) || (argc > 3)) { 5800c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim fputs(_("Usage: e2label device [newlabel]\n"), stderr); 5810c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach exit(1); 5822f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach } 5832f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach io_options = strchr(argv[1], '?'); 584dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (io_options) 585dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *io_options++ = 0; 5860c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach device_name = blkid_get_devname(NULL, argv[1], NULL); 5870c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim if (!device_name) { 5880c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim com_err("e2label", 0, _("Unable to resolve '%s'"), 5890c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim argv[1]); 5900c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim exit(1); 5910c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim } 5927a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach open_flag = EXT2_FLAG_JOURNAL_DEV_OK; 5937a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach if (argc == 3) { 5947a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach open_flag |= EXT2_FLAG_RW; 5957a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach L_flag = 1; 59636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines new_label = argv[2]; 5977a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach } else 5987a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach print_label++; 5997a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach} 6007a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach 6017a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbachstatic time_t parse_time(char *str) 6027a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach{ 6037a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach struct tm ts; 6047a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach 6057a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach if (strcmp(str, "now") == 0) { 6067a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach return (time(0)); 6077a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach } 6087a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach memset(&ts, 0, sizeof(ts)); 6097a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach#ifdef HAVE_STRPTIME 6107a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach strptime(str, "%Y%m%d%H%M%S", &ts); 6117a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach#else 6127a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach sscanf(str, "%4d%2d%2d%2d%2d%2d", &ts.tm_year, &ts.tm_mon, 61336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines &ts.tm_mday, &ts.tm_hour, &ts.tm_min, &ts.tm_sec); 61436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ts.tm_year -= 1900; 61536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ts.tm_mon -= 1; 61636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ts.tm_year < 0 || ts.tm_mon < 0 || ts.tm_mon > 11 || 61736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ts.tm_mday < 0 || ts.tm_mday > 31 || ts.tm_hour > 23 || 618dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ts.tm_min > 59 || ts.tm_sec > 61) 61936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ts.tm_mday = 0; 62036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif 6217a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach if (ts.tm_mday == 0) { 6227a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach com_err(program_name, 0, 6237a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach _("Couldn't parse date/time specifier: %s"), 6247a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach str); 6257a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach usage(); 6267a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach } 6277a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach ts.tm_isdst = -1; 6287a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach return (mktime(&ts)); 6297a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach} 6307a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach 6317a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbachstatic void parse_tune2fs_options(int argc, char **argv) 6327a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach{ 633dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines int c; 634dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines char *tmp; 6357a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach struct group *gr; 6367a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach struct passwd *pw; 637d832fa053b86f42a5bc1e55e979b61c1115a8053Bill Wendling 638c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach open_flag = 0; 639679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach 640662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach printf("tune2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE); 641662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach while ((c = getopt(argc, argv, "c:e:fg:i:jlm:o:r:s:u:C:E:I:J:L:M:O:T:U:")) != EOF) 642b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling switch (c) { 6436ec6eeb692fa11b569af8b69b2bb11cc84f04926Jim Grosbach case 'c': 64401086451393ef33e82b6fad623989dd97dd70edfJim Grosbach max_mount_count = strtol(optarg, &tmp, 0); 645b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling if (*tmp || max_mount_count > 16000) { 646d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach com_err(program_name, 0, 647b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling _("bad mounts count - %s"), 648b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling optarg); 6496ec6eeb692fa11b569af8b69b2bb11cc84f04926Jim Grosbach usage(); 650e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach } 651b492a7c2134d3886f545f1b5ea55115d71529a10Jim Grosbach if (max_mount_count == 0) 652dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling max_mount_count = -1; 653dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling c_flag = 1; 6542f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach open_flag = EXT2_FLAG_RW; 655662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach break; 656662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach case 'C': 657662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach mount_count = strtoul(optarg, &tmp, 0); 658cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy if (*tmp || mount_count > 16000) { 659cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy com_err(program_name, 0, 6607b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach _("bad mounts count - %s"), 661685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim optarg); 662685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim usage(); 663662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach } 664b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling C_flag = 1; 665b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling open_flag = EXT2_FLAG_RW; 666d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson break; 667c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson case 'e': 668c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson if (strcmp(optarg, "continue") == 0) 669d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson errors = EXT2_ERRORS_CONTINUE; 670a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson else if (strcmp(optarg, "remount-ro") == 0) 671662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach errors = EXT2_ERRORS_RO; 67209aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling else if (strcmp(optarg, "panic") == 0) 673f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng errors = EXT2_ERRORS_PANIC; 674f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng else { 675f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng com_err(program_name, 0, 676f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng _("bad error behavior - %s"), 67736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines optarg); 678dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines usage(); 679dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 680dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines e_flag = 1; 681dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines open_flag = EXT2_FLAG_RW; 682dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines break; 68336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 'E': 68436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines extended_cmd = optarg; 68536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines open_flag |= EXT2_FLAG_RW; 68636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 68736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 'f': /* Force */ 68836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines f_flag = 1; 68936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 69036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 'g': 69136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines resgid = strtoul(optarg, &tmp, 0); 69236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (*tmp) { 69336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines gr = getgrnam(optarg); 69436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (gr == NULL) 69536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines tmp = optarg; 69636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else { 69736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines resgid = gr->gr_gid; 69836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *tmp = 0; 69936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 70036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 70136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (*tmp) { 70236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines com_err(program_name, 0, 70336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines _("bad gid/group name - %s"), 70436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines optarg); 70536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines usage(); 70636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 70736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines g_flag = 1; 70836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines open_flag = EXT2_FLAG_RW; 70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 71036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 'i': 71136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines interval = strtoul(optarg, &tmp, 0); 71236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (*tmp) { 71336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 's': 71436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines tmp++; 71536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 71636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case '\0': 71736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 'd': 71836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 'D': /* days */ 71936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines interval *= 86400; 72036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (*tmp != '\0') 72136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines tmp++; 72236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 72336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 'm': 72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 'M': /* months! */ 72536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines interval *= 86400 * 30; 72636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines tmp++; 72736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 72836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 'w': 729662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach case 'W': /* weeks */ 730679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach interval *= 86400 * 7; 731679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach tmp++; 732679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach break; 733cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer } 73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (*tmp) { 73536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines com_err(program_name, 0, 736c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach _("bad interval - %s"), optarg); 737dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines usage(); 738d832fa053b86f42a5bc1e55e979b61c1115a8053Bill Wendling } 739d832fa053b86f42a5bc1e55e979b61c1115a8053Bill Wendling i_flag = 1; 740d832fa053b86f42a5bc1e55e979b61c1115a8053Bill Wendling open_flag = EXT2_FLAG_RW; 741d832fa053b86f42a5bc1e55e979b61c1115a8053Bill Wendling break; 742679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach case 'j': 74336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!journal_size) 74436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines journal_size = -1; 745dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines open_flag = EXT2_FLAG_RW; 74636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 747dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case 'J': 748dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines parse_journal_opts(optarg); 749dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines open_flag = EXT2_FLAG_RW; 75036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 751cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer case 'l': 752cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer l_flag = 1; 753cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer break; 75436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 'L': 75536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines new_label = optarg; 75636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines L_flag = 1; 75736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines open_flag |= EXT2_FLAG_RW | 758d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim EXT2_FLAG_JOURNAL_DEV_OK; 75952e635ea3512cfcd03587201b20100074e5b6ac9Bill Wendling break; 760cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer case 'm': 761dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines reserved_ratio = strtod(optarg, &tmp); 762dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (*tmp || reserved_ratio > 50 || 763dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines reserved_ratio < 0) { 764dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines com_err(program_name, 0, 765dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines _("bad reserved block ratio - %s"), 766dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines optarg); 767dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines usage(); 768dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 769dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines m_flag = 1; 770cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer open_flag = EXT2_FLAG_RW; 771cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer break; 772cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer case 'M': 773cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer new_last_mounted = optarg; 774cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer M_flag = 1; 775cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer open_flag = EXT2_FLAG_RW; 776cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer break; 77736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 'o': 77836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (mntopts_cmd) { 779cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer com_err(program_name, 0, 78036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines _("-o may only be specified once")); 78136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines usage(); 782cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer } 783cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer mntopts_cmd = optarg; 784cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer open_flag = EXT2_FLAG_RW; 785cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer break; 786cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer 787cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer case 'O': 7885510728d28bb1ee04abc32da3d21b7df12948053Charles Davis if (features_cmd) { 789cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer com_err(program_name, 0, 7905510728d28bb1ee04abc32da3d21b7df12948053Charles Davis _("-O may only be specified once")); 79136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines usage(); 792cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer } 793cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer features_cmd = optarg; 794cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer open_flag = EXT2_FLAG_RW; 79536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 796cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer case 'r': 7975510728d28bb1ee04abc32da3d21b7df12948053Charles Davis reserved_blocks = strtoul(optarg, &tmp, 0); 798cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer if (*tmp) { 799cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer com_err(program_name, 0, 800cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer _("bad reserved blocks count - %s"), 801cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer optarg); 802f73fd7278f2bebd435c84c55a79db8ccb07d3534Jim Grosbach usage(); 803d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim } 804c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling r_flag = 1; 805c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling open_flag = EXT2_FLAG_RW; 80636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 80736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 's': /* Deprecated */ 8081721324d97e2b05c9276ffe116dfb6c808521c2bOwen Anderson s_flag = atoi(optarg); 809912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar open_flag = EXT2_FLAG_RW; 810dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines break; 811dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case 'T': 812dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines T_flag = 1; 8135510728d28bb1ee04abc32da3d21b7df12948053Charles Davis last_check_time = parse_time(optarg); 8145510728d28bb1ee04abc32da3d21b7df12948053Charles Davis open_flag = EXT2_FLAG_RW; 8155510728d28bb1ee04abc32da3d21b7df12948053Charles Davis break; 8165510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case 'u': 8175510728d28bb1ee04abc32da3d21b7df12948053Charles Davis resuid = strtoul(optarg, &tmp, 0); 8185510728d28bb1ee04abc32da3d21b7df12948053Charles Davis if (*tmp) { 8195510728d28bb1ee04abc32da3d21b7df12948053Charles Davis pw = getpwnam(optarg); 8205510728d28bb1ee04abc32da3d21b7df12948053Charles Davis if (pw == NULL) 8215510728d28bb1ee04abc32da3d21b7df12948053Charles Davis tmp = optarg; 8225510728d28bb1ee04abc32da3d21b7df12948053Charles Davis else { 8235510728d28bb1ee04abc32da3d21b7df12948053Charles Davis resuid = pw->pw_uid; 82419d54337169ae4af2d44ae39664d0bac1ae0309cQuentin Colombet *tmp = 0; 82519d54337169ae4af2d44ae39664d0bac1ae0309cQuentin Colombet } 8261721324d97e2b05c9276ffe116dfb6c808521c2bOwen Anderson } 827dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (*tmp) { 828dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines com_err(program_name, 0, 829dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines _("bad uid/user name - %s"), 830dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines optarg); 831dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines usage(); 832dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 833dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines u_flag = 1; 834dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines open_flag = EXT2_FLAG_RW; 83536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 83636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 'U': 83736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines new_UUID = optarg; 83836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines U_flag = 1; 83936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines open_flag = EXT2_FLAG_RW | 84036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EXT2_FLAG_JOURNAL_DEV_OK; 84136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 84236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 'I': 84336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines new_inode_size = strtoul(optarg, &tmp, 0); 84436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (*tmp) { 84536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines com_err(program_name, 0, 84636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines _("bad inode size - %s"), 847d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim optarg); 84836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines usage(); 84936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 85036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!((new_inode_size & 85136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (new_inode_size - 1)) == 0)) { 85236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines com_err(program_name, 0, 85336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines _("Inode size must be a " 85436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "power of two- %s"), 85536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines optarg); 85636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines usage(); 85736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 85836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines open_flag = EXT2_FLAG_RW; 85936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I_flag = 1; 86036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 861 default: 862 usage(); 863 } 864 if (optind < argc - 1 || optind == argc) 865 usage(); 866 if (!open_flag && !l_flag) 867 usage(); 868 io_options = strchr(argv[optind], '?'); 869 if (io_options) 870 *io_options++ = 0; 871 device_name = blkid_get_devname(NULL, argv[optind], NULL); 872 if (!device_name) { 873 com_err("tune2fs", 0, _("Unable to resolve '%s'"), 874 argv[optind]); 875 exit(1); 876 } 877} 878 879#ifdef CONFIG_BUILD_FINDFS 880void do_findfs(int argc, char **argv) 881{ 882 char *dev; 883 884 if ((argc != 2) || 885 (strncmp(argv[1], "LABEL=", 6) && strncmp(argv[1], "UUID=", 5))) { 886 fprintf(stderr, "Usage: findfs LABEL=<label>|UUID=<uuid>\n"); 887 exit(2); 888 } 889 dev = blkid_get_devname(NULL, argv[1], NULL); 890 if (!dev) { 891 com_err("findfs", 0, _("Unable to resolve '%s'"), 892 argv[1]); 893 exit(1); 894 } 895 puts(dev); 896 exit(0); 897} 898#endif 899 900static void parse_extended_opts(ext2_filsys fs, const char *opts) 901{ 902 char *buf, *token, *next, *p, *arg; 903 int len, hash_alg; 904 int r_usage = 0; 905 906 len = strlen(opts); 907 buf = malloc(len+1); 908 if (!buf) { 909 fprintf(stderr, 910 _("Couldn't allocate memory to parse options!\n")); 911 exit(1); 912 } 913 strcpy(buf, opts); 914 for (token = buf; token && *token; token = next) { 915 p = strchr(token, ','); 916 next = 0; 917 if (p) { 918 *p = 0; 919 next = p+1; 920 } 921 arg = strchr(token, '='); 922 if (arg) { 923 *arg = 0; 924 arg++; 925 } 926 if (!strcmp(token, "test_fs")) { 927 fs->super->s_flags |= EXT2_FLAGS_TEST_FILESYS; 928 printf("Setting test filesystem flag\n"); 929 ext2fs_mark_super_dirty(fs); 930 } else if (!strcmp(token, "^test_fs")) { 931 fs->super->s_flags &= ~EXT2_FLAGS_TEST_FILESYS; 932 printf("Clearing test filesystem flag\n"); 933 ext2fs_mark_super_dirty(fs); 934 } else if (strcmp(token, "stride") == 0) { 935 if (!arg) { 936 r_usage++; 937 continue; 938 } 939 stride = strtoul(arg, &p, 0); 940 if (*p || (stride == 0)) { 941 fprintf(stderr, 942 _("Invalid RAID stride: %s\n"), 943 arg); 944 r_usage++; 945 continue; 946 } 947 stride_set = 1; 948 } else if (strcmp(token, "stripe-width") == 0 || 949 strcmp(token, "stripe_width") == 0) { 950 if (!arg) { 951 r_usage++; 952 continue; 953 } 954 stripe_width = strtoul(arg, &p, 0); 955 if (*p || (stripe_width == 0)) { 956 fprintf(stderr, 957 _("Invalid RAID stripe-width: %s\n"), 958 arg); 959 r_usage++; 960 continue; 961 } 962 stripe_width_set = 1; 963 } else if (strcmp(token, "hash_alg") == 0 || 964 strcmp(token, "hash-alg") == 0) { 965 if (!arg) { 966 r_usage++; 967 continue; 968 } 969 hash_alg = e2p_string2hash(arg); 970 if (hash_alg < 0) { 971 fprintf(stderr, 972 _("Invalid hash algorithm: %s\n"), 973 arg); 974 r_usage++; 975 continue; 976 } 977 fs->super->s_def_hash_version = hash_alg; 978 printf(_("Setting default hash algorithm " 979 "to %s (%d)\n"), 980 arg, hash_alg); 981 ext2fs_mark_super_dirty(fs); 982 } else if (strcmp(token, "mount-options")) { 983 if (!arg) { 984 r_usage++; 985 continue; 986 } 987 if (strlen(arg) >= sizeof(fs->super->s_mount_opts)) { 988 fprintf(stderr, 989 "Extended mount options too long\n"); 990 continue; 991 } 992 strcpy(fs->super->s_mount_opts, arg); 993 ext2fs_mark_super_dirty(fs); 994 } else 995 r_usage++; 996 } 997 if (r_usage) { 998 fprintf(stderr, _("\nBad options specified.\n\n" 999 "Extended options are separated by commas, " 1000 "and may take an argument which\n" 1001 "\tis set off by an equals ('=') sign.\n\n" 1002 "Valid extended options are:\n" 1003 "\tstride=<RAID per-disk chunk size in blocks>\n" 1004 "\tstripe_width=<RAID stride*data disks in blocks>\n" 1005 "\thash_alg=<hash algorithm>\n" 1006 "\ttest_fs\n" 1007 "\t^test_fs\n")); 1008 free(buf); 1009 exit(1); 1010 } 1011 free(buf); 1012} 1013 1014/* 1015 * Fill in the block bitmap bmap with the information regarding the 1016 * blocks to be moved 1017 */ 1018static int get_move_bitmaps(ext2_filsys fs, int new_ino_blks_per_grp, 1019 ext2fs_block_bitmap bmap) 1020{ 1021 dgrp_t i; 1022 int retval; 1023 ext2_badblocks_list bb_list = 0; 1024 blk_t j, needed_blocks = 0; 1025 blk_t start_blk, end_blk; 1026 1027 retval = ext2fs_read_bb_inode(fs, &bb_list); 1028 if (retval) 1029 return retval; 1030 1031 for (i = 0; i < fs->group_desc_count; i++) { 1032 start_blk = fs->group_desc[i].bg_inode_table + 1033 fs->inode_blocks_per_group; 1034 1035 end_blk = fs->group_desc[i].bg_inode_table + 1036 new_ino_blks_per_grp; 1037 1038 for (j = start_blk; j < end_blk; j++) { 1039 if (ext2fs_test_block_bitmap(fs->block_map, j)) { 1040 /* 1041 * IF the block is a bad block we fail 1042 */ 1043 if (ext2fs_badblocks_list_test(bb_list, j)) { 1044 ext2fs_badblocks_list_free(bb_list); 1045 return ENOSPC; 1046 } 1047 1048 ext2fs_mark_block_bitmap(bmap, j); 1049 } else { 1050 /* 1051 * We are going to use this block for 1052 * inode table. So mark them used. 1053 */ 1054 ext2fs_mark_block_bitmap(fs->block_map, j); 1055 } 1056 } 1057 needed_blocks += end_blk - start_blk; 1058 } 1059 1060 ext2fs_badblocks_list_free(bb_list); 1061 if (needed_blocks > fs->super->s_free_blocks_count) 1062 return ENOSPC; 1063 1064 return 0; 1065} 1066 1067static int ext2fs_is_meta_block(ext2_filsys fs, blk_t blk) 1068{ 1069 dgrp_t group; 1070 group = ext2fs_group_of_blk(fs, blk); 1071 if (fs->group_desc[group].bg_block_bitmap == blk) 1072 return 1; 1073 if (fs->group_desc[group].bg_inode_bitmap == blk) 1074 return 1; 1075 return 0; 1076} 1077 1078static int ext2fs_is_block_in_group(ext2_filsys fs, dgrp_t group, blk_t blk) 1079{ 1080 blk_t start_blk, end_blk; 1081 start_blk = fs->super->s_first_data_block + 1082 EXT2_BLOCKS_PER_GROUP(fs->super) * group; 1083 /* 1084 * We cannot get new block beyond end_blk for for the last block group 1085 * so we can check with EXT2_BLOCKS_PER_GROUP even for last block group 1086 */ 1087 end_blk = start_blk + EXT2_BLOCKS_PER_GROUP(fs->super); 1088 if (blk >= start_blk && blk <= end_blk) 1089 return 1; 1090 return 0; 1091} 1092 1093static int move_block(ext2_filsys fs, ext2fs_block_bitmap bmap) 1094{ 1095 1096 char *buf; 1097 dgrp_t group; 1098 errcode_t retval; 1099 int meta_data = 0; 1100 blk_t blk, new_blk, goal; 1101 struct blk_move *bmv; 1102 1103 retval = ext2fs_get_mem(fs->blocksize, &buf); 1104 if (retval) 1105 return retval; 1106 1107 for (new_blk = blk = fs->super->s_first_data_block; 1108 blk < fs->super->s_blocks_count; blk++) { 1109 if (!ext2fs_test_block_bitmap(bmap, blk)) 1110 continue; 1111 1112 if (ext2fs_is_meta_block(fs, blk)) { 1113 /* 1114 * If the block is mapping a fs meta data block 1115 * like group desc/block bitmap/inode bitmap. We 1116 * should find a block in the same group and fix 1117 * the respective fs metadata pointers. Otherwise 1118 * fail 1119 */ 1120 group = ext2fs_group_of_blk(fs, blk); 1121 goal = ext2fs_group_first_block(fs, group); 1122 meta_data = 1; 1123 1124 } else { 1125 goal = new_blk; 1126 } 1127 retval = ext2fs_new_block(fs, goal, NULL, &new_blk); 1128 if (retval) 1129 goto err_out; 1130 1131 /* new fs meta data block should be in the same group */ 1132 if (meta_data && !ext2fs_is_block_in_group(fs, group, new_blk)) { 1133 retval = ENOSPC; 1134 goto err_out; 1135 } 1136 1137 /* Mark this block as allocated */ 1138 ext2fs_mark_block_bitmap(fs->block_map, new_blk); 1139 1140 /* Add it to block move list */ 1141 retval = ext2fs_get_mem(sizeof(struct blk_move), &bmv); 1142 if (retval) 1143 goto err_out; 1144 1145 bmv->old_loc = blk; 1146 bmv->new_loc = new_blk; 1147 1148 list_add(&(bmv->list), &blk_move_list); 1149 1150 retval = io_channel_read_blk(fs->io, blk, 1, buf); 1151 if (retval) 1152 goto err_out; 1153 1154 retval = io_channel_write_blk(fs->io, new_blk, 1, buf); 1155 if (retval) 1156 goto err_out; 1157 } 1158 1159err_out: 1160 ext2fs_free_mem(&buf); 1161 return retval; 1162} 1163 1164static blk_t translate_block(blk_t blk) 1165{ 1166 struct list_head *entry; 1167 struct blk_move *bmv; 1168 1169 list_for_each(entry, &blk_move_list) { 1170 bmv = list_entry(entry, struct blk_move, list); 1171 if (bmv->old_loc == blk) 1172 return bmv->new_loc; 1173 } 1174 1175 return 0; 1176} 1177 1178static int process_block(ext2_filsys fs EXT2FS_ATTR((unused)), 1179 blk_t *block_nr, 1180 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)), 1181 blk_t ref_block EXT2FS_ATTR((unused)), 1182 int ref_offset EXT2FS_ATTR((unused)), 1183 void *priv_data) 1184{ 1185 int ret = 0; 1186 blk_t new_blk; 1187 ext2fs_block_bitmap bmap = (ext2fs_block_bitmap) priv_data; 1188 1189 if (!ext2fs_test_block_bitmap(bmap, *block_nr)) 1190 return 0; 1191 new_blk = translate_block(*block_nr); 1192 if (new_blk) { 1193 *block_nr = new_blk; 1194 /* 1195 * This will force the ext2fs_write_inode in the iterator 1196 */ 1197 ret |= BLOCK_CHANGED; 1198 } 1199 1200 return ret; 1201} 1202 1203static int inode_scan_and_fix(ext2_filsys fs, ext2fs_block_bitmap bmap) 1204{ 1205 errcode_t retval = 0; 1206 ext2_ino_t ino; 1207 blk_t blk; 1208 char *block_buf = 0; 1209 struct ext2_inode inode; 1210 ext2_inode_scan scan = NULL; 1211 1212 retval = ext2fs_get_mem(fs->blocksize * 3, &block_buf); 1213 if (retval) 1214 return retval; 1215 1216 retval = ext2fs_open_inode_scan(fs, 0, &scan); 1217 if (retval) 1218 goto err_out; 1219 1220 while (1) { 1221 retval = ext2fs_get_next_inode(scan, &ino, &inode); 1222 if (retval) 1223 goto err_out; 1224 1225 if (!ino) 1226 break; 1227 1228 if (inode.i_links_count == 0) 1229 continue; /* inode not in use */ 1230 1231 /* FIXME!! 1232 * If we end up modifying the journal inode 1233 * the sb->s_jnl_blocks will differ. But a 1234 * subsequent e2fsck fixes that. 1235 * Do we need to fix this ?? 1236 */ 1237 1238 if (inode.i_file_acl && 1239 ext2fs_test_block_bitmap(bmap, inode.i_file_acl)) { 1240 blk = translate_block(inode.i_file_acl); 1241 if (!blk) 1242 continue; 1243 1244 inode.i_file_acl = blk; 1245 1246 /* 1247 * Write the inode to disk so that inode table 1248 * resizing can work 1249 */ 1250 retval = ext2fs_write_inode(fs, ino, &inode); 1251 if (retval) 1252 goto err_out; 1253 } 1254 1255 if (!ext2fs_inode_has_valid_blocks(&inode)) 1256 continue; 1257 1258 retval = ext2fs_block_iterate2(fs, ino, 0, block_buf, 1259 process_block, bmap); 1260 if (retval) 1261 goto err_out; 1262 1263 } 1264 1265err_out: 1266 ext2fs_free_mem(&block_buf); 1267 1268 return retval; 1269} 1270 1271/* 1272 * We need to scan for inode and block bitmaps that may need to be 1273 * moved. This can take place if the filesystem was formatted for 1274 * RAID arrays using the mke2fs's extended option "stride". 1275 */ 1276static int group_desc_scan_and_fix(ext2_filsys fs, ext2fs_block_bitmap bmap) 1277{ 1278 dgrp_t i; 1279 blk_t blk, new_blk; 1280 1281 for (i = 0; i < fs->group_desc_count; i++) { 1282 blk = fs->group_desc[i].bg_block_bitmap; 1283 if (ext2fs_test_block_bitmap(bmap, blk)) { 1284 new_blk = translate_block(blk); 1285 if (!new_blk) 1286 continue; 1287 fs->group_desc[i].bg_block_bitmap = new_blk; 1288 } 1289 1290 blk = fs->group_desc[i].bg_inode_bitmap; 1291 if (ext2fs_test_block_bitmap(bmap, blk)) { 1292 new_blk = translate_block(blk); 1293 if (!new_blk) 1294 continue; 1295 fs->group_desc[i].bg_inode_bitmap = new_blk; 1296 } 1297 } 1298 return 0; 1299} 1300 1301static int expand_inode_table(ext2_filsys fs, unsigned long new_ino_size) 1302{ 1303 dgrp_t i; 1304 blk_t blk; 1305 errcode_t retval; 1306 int new_ino_blks_per_grp; 1307 unsigned int j; 1308 char *old_itable = NULL, *new_itable = NULL; 1309 char *tmp_old_itable = NULL, *tmp_new_itable = NULL; 1310 unsigned long old_ino_size; 1311 int old_itable_size, new_itable_size; 1312 1313 old_itable_size = fs->inode_blocks_per_group * fs->blocksize; 1314 old_ino_size = EXT2_INODE_SIZE(fs->super); 1315 1316 new_ino_blks_per_grp = ext2fs_div_ceil( 1317 EXT2_INODES_PER_GROUP(fs->super) * 1318 new_ino_size, 1319 fs->blocksize); 1320 1321 new_itable_size = new_ino_blks_per_grp * fs->blocksize; 1322 1323 retval = ext2fs_get_mem(old_itable_size, &old_itable); 1324 if (retval) 1325 return retval; 1326 1327 retval = ext2fs_get_mem(new_itable_size, &new_itable); 1328 if (retval) 1329 goto err_out; 1330 1331 tmp_old_itable = old_itable; 1332 tmp_new_itable = new_itable; 1333 1334 for (i = 0; i < fs->group_desc_count; i++) { 1335 blk = fs->group_desc[i].bg_inode_table; 1336 retval = io_channel_read_blk(fs->io, blk, 1337 fs->inode_blocks_per_group, old_itable); 1338 if (retval) 1339 goto err_out; 1340 1341 for (j = 0; j < EXT2_INODES_PER_GROUP(fs->super); j++) { 1342 memcpy(new_itable, old_itable, old_ino_size); 1343 1344 memset(new_itable+old_ino_size, 0, 1345 new_ino_size - old_ino_size); 1346 1347 new_itable += new_ino_size; 1348 old_itable += old_ino_size; 1349 } 1350 1351 /* reset the pointer */ 1352 old_itable = tmp_old_itable; 1353 new_itable = tmp_new_itable; 1354 1355 retval = io_channel_write_blk(fs->io, blk, 1356 new_ino_blks_per_grp, new_itable); 1357 if (retval) 1358 goto err_out; 1359 } 1360 1361 /* Update the meta data */ 1362 fs->inode_blocks_per_group = new_ino_blks_per_grp; 1363 fs->super->s_inode_size = new_ino_size; 1364 1365err_out: 1366 if (old_itable) 1367 ext2fs_free_mem(&old_itable); 1368 1369 if (new_itable) 1370 ext2fs_free_mem(&new_itable); 1371 1372 return retval; 1373} 1374 1375static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs) 1376{ 1377 blk_t blk; 1378 ext2_ino_t ino; 1379 unsigned int group = 0; 1380 unsigned int count = 0; 1381 int total_free = 0; 1382 int group_free = 0; 1383 1384 /* 1385 * First calculate the block statistics 1386 */ 1387 for (blk = fs->super->s_first_data_block; 1388 blk < fs->super->s_blocks_count; blk++) { 1389 if (!ext2fs_fast_test_block_bitmap(fs->block_map, blk)) { 1390 group_free++; 1391 total_free++; 1392 } 1393 count++; 1394 if ((count == fs->super->s_blocks_per_group) || 1395 (blk == fs->super->s_blocks_count-1)) { 1396 fs->group_desc[group++].bg_free_blocks_count = 1397 group_free; 1398 count = 0; 1399 group_free = 0; 1400 } 1401 } 1402 fs->super->s_free_blocks_count = total_free; 1403 1404 /* 1405 * Next, calculate the inode statistics 1406 */ 1407 group_free = 0; 1408 total_free = 0; 1409 count = 0; 1410 group = 0; 1411 1412 /* Protect loop from wrap-around if s_inodes_count maxed */ 1413 for (ino = 1; ino <= fs->super->s_inodes_count && ino > 0; ino++) { 1414 if (!ext2fs_fast_test_inode_bitmap(fs->inode_map, ino)) { 1415 group_free++; 1416 total_free++; 1417 } 1418 count++; 1419 if ((count == fs->super->s_inodes_per_group) || 1420 (ino == fs->super->s_inodes_count)) { 1421 fs->group_desc[group++].bg_free_inodes_count = 1422 group_free; 1423 count = 0; 1424 group_free = 0; 1425 } 1426 } 1427 fs->super->s_free_inodes_count = total_free; 1428 ext2fs_mark_super_dirty(fs); 1429 return 0; 1430} 1431 1432#define list_for_each_safe(pos, pnext, head) \ 1433 for (pos = (head)->next, pnext = pos->next; pos != (head); \ 1434 pos = pnext, pnext = pos->next) 1435 1436static void free_blk_move_list(void) 1437{ 1438 struct list_head *entry, *tmp; 1439 struct blk_move *bmv; 1440 1441 list_for_each_safe(entry, tmp, &blk_move_list) { 1442 bmv = list_entry(entry, struct blk_move, list); 1443 list_del(entry); 1444 ext2fs_free_mem(&bmv); 1445 } 1446 return; 1447} 1448 1449static int resize_inode(ext2_filsys fs, unsigned long new_size) 1450{ 1451 errcode_t retval; 1452 int new_ino_blks_per_grp; 1453 ext2fs_block_bitmap bmap; 1454 1455 ext2fs_read_inode_bitmap(fs); 1456 ext2fs_read_block_bitmap(fs); 1457 INIT_LIST_HEAD(&blk_move_list); 1458 1459 1460 new_ino_blks_per_grp = ext2fs_div_ceil( 1461 EXT2_INODES_PER_GROUP(fs->super)* 1462 new_size, 1463 fs->blocksize); 1464 1465 /* We may change the file system. 1466 * Mark the file system as invalid so that 1467 * the user is prompted to run fsck. 1468 */ 1469 fs->super->s_state &= ~EXT2_VALID_FS; 1470 1471 retval = ext2fs_allocate_block_bitmap(fs, _("blocks to be moved"), 1472 &bmap); 1473 if (retval) { 1474 fputs(_("Failed to allocate block bitmap when " 1475 "increasing inode size\n"), stderr); 1476 return retval; 1477 } 1478 retval = get_move_bitmaps(fs, new_ino_blks_per_grp, bmap); 1479 if (retval) { 1480 fputs(_("Not enough space to increase inode size \n"), stderr); 1481 goto err_out; 1482 } 1483 retval = move_block(fs, bmap); 1484 if (retval) { 1485 fputs(_("Failed to relocate blocks during inode resize \n"), 1486 stderr); 1487 goto err_out; 1488 } 1489 retval = inode_scan_and_fix(fs, bmap); 1490 if (retval) 1491 goto err_out_undo; 1492 1493 retval = group_desc_scan_and_fix(fs, bmap); 1494 if (retval) 1495 goto err_out_undo; 1496 1497 retval = expand_inode_table(fs, new_size); 1498 if (retval) 1499 goto err_out_undo; 1500 1501 ext2fs_calculate_summary_stats(fs); 1502 1503 fs->super->s_state |= EXT2_VALID_FS; 1504 /* mark super block and block bitmap as dirty */ 1505 ext2fs_mark_super_dirty(fs); 1506 ext2fs_mark_bb_dirty(fs); 1507 1508err_out: 1509 free_blk_move_list(); 1510 ext2fs_free_block_bitmap(bmap); 1511 1512 return retval; 1513 1514err_out_undo: 1515 free_blk_move_list(); 1516 ext2fs_free_block_bitmap(bmap); 1517 fputs(_("Error in resizing the inode size.\n" 1518 "Run e2undo to undo the " 1519 "file system changes. \n"), stderr); 1520 1521 return retval; 1522} 1523 1524static int tune2fs_setup_tdb(const char *name, io_manager *io_ptr) 1525{ 1526 errcode_t retval = 0; 1527 const char *tdb_dir; 1528 char *tdb_file; 1529 char *dev_name, *tmp_name; 1530 1531#if 0 /* FIXME!! */ 1532 /* 1533 * Configuration via a conf file would be 1534 * nice 1535 */ 1536 profile_get_string(profile, "scratch_files", 1537 "directory", 0, 0, 1538 &tdb_dir); 1539#endif 1540 tmp_name = strdup(name); 1541 if (!tmp_name) { 1542 alloc_fn_fail: 1543 com_err(program_name, ENOMEM, 1544 _("Couldn't allocate memory for tdb filename\n")); 1545 return ENOMEM; 1546 } 1547 dev_name = basename(tmp_name); 1548 1549 tdb_dir = getenv("E2FSPROGS_UNDO_DIR"); 1550 if (!tdb_dir) 1551 tdb_dir = "/var/lib/e2fsprogs"; 1552 1553 if (!strcmp(tdb_dir, "none") || (tdb_dir[0] == 0) || 1554 access(tdb_dir, W_OK)) 1555 return 0; 1556 1557 tdb_file = malloc(strlen(tdb_dir) + 9 + strlen(dev_name) + 7 + 1); 1558 if (!tdb_file) 1559 goto alloc_fn_fail; 1560 sprintf(tdb_file, "%s/tune2fs-%s.e2undo", tdb_dir, dev_name); 1561 1562 if (!access(tdb_file, F_OK)) { 1563 if (unlink(tdb_file) < 0) { 1564 retval = errno; 1565 com_err(program_name, retval, 1566 _("while trying to delete %s"), 1567 tdb_file); 1568 free(tdb_file); 1569 return retval; 1570 } 1571 } 1572 1573 set_undo_io_backing_manager(*io_ptr); 1574 *io_ptr = undo_io_manager; 1575 set_undo_io_backup_file(tdb_file); 1576 printf(_("To undo the tune2fs operation please run " 1577 "the command\n e2undo %s %s\n\n"), 1578 tdb_file, name); 1579 free(tdb_file); 1580 free(tmp_name); 1581 return retval; 1582} 1583 1584int main(int argc, char **argv) 1585{ 1586 errcode_t retval; 1587 ext2_filsys fs; 1588 struct ext2_super_block *sb; 1589 io_manager io_ptr, io_ptr_orig = NULL; 1590 1591#ifdef ENABLE_NLS 1592 setlocale(LC_MESSAGES, ""); 1593 setlocale(LC_CTYPE, ""); 1594 bindtextdomain(NLS_CAT_NAME, LOCALEDIR); 1595 textdomain(NLS_CAT_NAME); 1596#endif 1597 if (argc && *argv) 1598 program_name = *argv; 1599 add_error_table(&et_ext2_error_table); 1600 1601#ifdef CONFIG_BUILD_FINDFS 1602 if (strcmp(get_progname(argv[0]), "findfs") == 0) 1603 do_findfs(argc, argv); 1604#endif 1605 if (strcmp(get_progname(argv[0]), "e2label") == 0) 1606 parse_e2label_options(argc, argv); 1607 else 1608 parse_tune2fs_options(argc, argv); 1609 1610#ifdef CONFIG_TESTIO_DEBUG 1611 if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_DEBUG")) { 1612 io_ptr = test_io_manager; 1613 test_io_backing_manager = unix_io_manager; 1614 } else 1615#endif 1616 io_ptr = unix_io_manager; 1617 1618retry_open: 1619 retval = ext2fs_open2(device_name, io_options, open_flag, 1620 0, 0, io_ptr, &fs); 1621 if (retval) { 1622 com_err(program_name, retval, 1623 _("while trying to open %s"), 1624 device_name); 1625 fprintf(stderr, 1626 _("Couldn't find valid filesystem superblock.\n")); 1627 exit(1); 1628 } 1629 1630 if (I_flag && !io_ptr_orig) { 1631 /* 1632 * Check the inode size is right so we can issue an 1633 * error message and bail before setting up the tdb 1634 * file. 1635 */ 1636 if (new_inode_size == EXT2_INODE_SIZE(fs->super)) { 1637 fprintf(stderr, _("The inode size is already %lu\n"), 1638 new_inode_size); 1639 exit(1); 1640 } 1641 if (new_inode_size < EXT2_INODE_SIZE(fs->super)) { 1642 fprintf(stderr, _("Shrinking the inode size is " 1643 "not supported\n")); 1644 exit(1); 1645 } 1646 1647 /* 1648 * If inode resize is requested use the 1649 * Undo I/O manager 1650 */ 1651 io_ptr_orig = io_ptr; 1652 retval = tune2fs_setup_tdb(device_name, &io_ptr); 1653 if (retval) 1654 exit(1); 1655 if (io_ptr != io_ptr_orig) { 1656 ext2fs_close(fs); 1657 goto retry_open; 1658 } 1659 } 1660 1661 sb = fs->super; 1662 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; 1663 1664 if (print_label) { 1665 /* For e2label emulation */ 1666 printf("%.*s\n", (int) sizeof(sb->s_volume_name), 1667 sb->s_volume_name); 1668 remove_error_table(&et_ext2_error_table); 1669 exit(0); 1670 } 1671 1672 retval = ext2fs_check_if_mounted(device_name, &mount_flags); 1673 if (retval) { 1674 com_err("ext2fs_check_if_mount", retval, 1675 _("while determining whether %s is mounted."), 1676 device_name); 1677 exit(1); 1678 } 1679 /* Normally we only need to write out the superblock */ 1680 fs->flags |= EXT2_FLAG_SUPER_ONLY; 1681 1682 if (c_flag) { 1683 sb->s_max_mnt_count = max_mount_count; 1684 ext2fs_mark_super_dirty(fs); 1685 printf(_("Setting maximal mount count to %d\n"), 1686 max_mount_count); 1687 } 1688 if (C_flag) { 1689 sb->s_mnt_count = mount_count; 1690 ext2fs_mark_super_dirty(fs); 1691 printf(_("Setting current mount count to %d\n"), mount_count); 1692 } 1693 if (e_flag) { 1694 sb->s_errors = errors; 1695 ext2fs_mark_super_dirty(fs); 1696 printf(_("Setting error behavior to %d\n"), errors); 1697 } 1698 if (g_flag) { 1699 sb->s_def_resgid = resgid; 1700 ext2fs_mark_super_dirty(fs); 1701 printf(_("Setting reserved blocks gid to %lu\n"), resgid); 1702 } 1703 if (i_flag) { 1704 sb->s_checkinterval = interval; 1705 ext2fs_mark_super_dirty(fs); 1706 printf(_("Setting interval between checks to %lu seconds\n"), 1707 interval); 1708 } 1709 if (m_flag) { 1710 sb->s_r_blocks_count = (unsigned int) (reserved_ratio * 1711 sb->s_blocks_count / 100.0); 1712 ext2fs_mark_super_dirty(fs); 1713 printf(_("Setting reserved blocks percentage to %g%% " 1714 "(%u blocks)\n"), 1715 reserved_ratio, sb->s_r_blocks_count); 1716 } 1717 if (r_flag) { 1718 if (reserved_blocks >= sb->s_blocks_count/2) { 1719 com_err(program_name, 0, 1720 _("reserved blocks count is too big (%lu)"), 1721 reserved_blocks); 1722 exit(1); 1723 } 1724 sb->s_r_blocks_count = reserved_blocks; 1725 ext2fs_mark_super_dirty(fs); 1726 printf(_("Setting reserved blocks count to %lu\n"), 1727 reserved_blocks); 1728 } 1729 if (s_flag == 1) { 1730 if (sb->s_feature_ro_compat & 1731 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) 1732 fputs(_("\nThe filesystem already has sparse " 1733 "superblocks.\n"), stderr); 1734 else { 1735 sb->s_feature_ro_compat |= 1736 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; 1737 sb->s_state &= ~EXT2_VALID_FS; 1738 ext2fs_mark_super_dirty(fs); 1739 printf(_("\nSparse superblock flag set. %s"), 1740 _(please_fsck)); 1741 } 1742 } 1743 if (s_flag == 0) { 1744 fputs(_("\nClearing the sparse superflag not supported.\n"), 1745 stderr); 1746 exit(1); 1747 } 1748 if (T_flag) { 1749 sb->s_lastcheck = last_check_time; 1750 ext2fs_mark_super_dirty(fs); 1751 printf(_("Setting time filesystem last checked to %s\n"), 1752 ctime(&last_check_time)); 1753 } 1754 if (u_flag) { 1755 sb->s_def_resuid = resuid; 1756 ext2fs_mark_super_dirty(fs); 1757 printf(_("Setting reserved blocks uid to %lu\n"), resuid); 1758 } 1759 if (L_flag) { 1760 if (strlen(new_label) > sizeof(sb->s_volume_name)) 1761 fputs(_("Warning: label too long, truncating.\n"), 1762 stderr); 1763 memset(sb->s_volume_name, 0, sizeof(sb->s_volume_name)); 1764 strncpy(sb->s_volume_name, new_label, 1765 sizeof(sb->s_volume_name)); 1766 ext2fs_mark_super_dirty(fs); 1767 } 1768 if (M_flag) { 1769 memset(sb->s_last_mounted, 0, sizeof(sb->s_last_mounted)); 1770 strncpy(sb->s_last_mounted, new_last_mounted, 1771 sizeof(sb->s_last_mounted)); 1772 ext2fs_mark_super_dirty(fs); 1773 } 1774 if (mntopts_cmd) 1775 update_mntopts(fs, mntopts_cmd); 1776 if (features_cmd) 1777 update_feature_set(fs, features_cmd); 1778 if (extended_cmd) 1779 parse_extended_opts(fs, extended_cmd); 1780 if (journal_size || journal_device) 1781 add_journal(fs); 1782 1783 if (U_flag) { 1784 int set_csum = 0; 1785 dgrp_t i; 1786 1787 if (sb->s_feature_ro_compat & 1788 EXT4_FEATURE_RO_COMPAT_GDT_CSUM) { 1789 /* 1790 * Determine if the block group checksums are 1791 * correct so we know whether or not to set 1792 * them later on. 1793 */ 1794 for (i = 0; i < fs->group_desc_count; i++) 1795 if (!ext2fs_group_desc_csum_verify(fs, i)) 1796 break; 1797 if (i >= fs->group_desc_count) 1798 set_csum = 1; 1799 } 1800 if ((strcasecmp(new_UUID, "null") == 0) || 1801 (strcasecmp(new_UUID, "clear") == 0)) { 1802 uuid_clear(sb->s_uuid); 1803 } else if (strcasecmp(new_UUID, "time") == 0) { 1804 uuid_generate_time(sb->s_uuid); 1805 } else if (strcasecmp(new_UUID, "random") == 0) { 1806 uuid_generate(sb->s_uuid); 1807 } else if (uuid_parse(new_UUID, sb->s_uuid)) { 1808 com_err(program_name, 0, _("Invalid UUID format\n")); 1809 exit(1); 1810 } 1811 if (set_csum) { 1812 for (i = 0; i < fs->group_desc_count; i++) 1813 ext2fs_group_desc_csum_set(fs, i); 1814 fs->flags &= ~EXT2_FLAG_SUPER_ONLY; 1815 } 1816 ext2fs_mark_super_dirty(fs); 1817 } 1818 if (I_flag) { 1819 if (mount_flags & EXT2_MF_MOUNTED) { 1820 fputs(_("The inode size may only be " 1821 "changed when the filesystem is " 1822 "unmounted.\n"), stderr); 1823 exit(1); 1824 } 1825 if (fs->super->s_feature_incompat & 1826 EXT4_FEATURE_INCOMPAT_FLEX_BG) { 1827 fputs(_("Changing the inode size not supported for " 1828 "filesystems with the flex_bg\n" 1829 "feature enabled.\n"), 1830 stderr); 1831 exit(1); 1832 } 1833 /* 1834 * We want to update group descriptor also 1835 * with the new free inode count 1836 */ 1837 fs->flags &= ~EXT2_FLAG_SUPER_ONLY; 1838 if (resize_inode(fs, new_inode_size) == 0) { 1839 printf(_("Setting inode size %lu\n"), 1840 new_inode_size); 1841 } 1842 } 1843 1844 if (l_flag) 1845 list_super(sb); 1846 if (stride_set) { 1847 sb->s_raid_stride = stride; 1848 ext2fs_mark_super_dirty(fs); 1849 printf(_("Setting stride size to %d\n"), stride); 1850 } 1851 if (stripe_width_set) { 1852 sb->s_raid_stripe_width = stripe_width; 1853 ext2fs_mark_super_dirty(fs); 1854 printf(_("Setting stripe width to %d\n"), stripe_width); 1855 } 1856 free(device_name); 1857 remove_error_table(&et_ext2_error_table); 1858 return (ext2fs_close(fs) ? 1 : 0); 1859} 1860