13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
24d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o * tune2fs.c - Change the file system parameters on an ext2 file system
33839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o *
43839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Copyright (C) 1992, 1993, 1994  Remy Card <card@masi.ibp.fr>
53839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o *                                 Laboratoire MASI, Institut Blaise Pascal
63839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o *                                 Universite Pierre et Marie Curie (Paris VI)
73839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o *
84d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o * Copyright 1995, 1996, 1997, 1998, 1999, 2000 by Theodore Ts'o.
919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o *
1019c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %Begin-Header%
1119c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * This file may be redistributed under the terms of the GNU Public
1219c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * License.
1319c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %End-Header%
143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * History:
183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 93/06/01	- Creation
193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 93/10/31	- Added the -c option to change the maximal mount counts
203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 93/12/14	- Added -l flag to list contents of superblock
213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o *                M.J.E. Mol (marcel@duteca.et.tudelft.nl)
223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o *                F.W. ten Wolde (franky@duteca.et.tudelft.nl)
233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 93/12/29	- Added the -e option to change errors behavior
243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 94/02/27	- Ported to use the ext2fs library
253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 94/03/06	- Added the checks interval from Uwe Ohse (uwe@tirka.gun.de)
263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
28ebabf2ad6d19af5c674b624bafe619dedbc94403Theodore Ts'o#define _XOPEN_SOURCE 600 /* for inclusion of strptime() */
293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <fcntl.h>
30f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#include <grp.h>
31a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#ifdef HAVE_GETOPT_H
323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <getopt.h>
33373b8337c7b6c6243810be250083fa4773891e92Theodore Ts'o#else
34373b8337c7b6c6243810be250083fa4773891e92Theodore Ts'oextern char *optarg;
35373b8337c7b6c6243810be250083fa4773891e92Theodore Ts'oextern int optind;
36a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#endif
37f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#include <pwd.h>
383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h>
39f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o#ifdef HAVE_STDLIB_H
403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdlib.h>
41f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o#endif
42e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef HAVE_STRINGS_H
43e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#include <strings.h>	/* for strcasecmp() */
44e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#else
45e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#define _BSD_SOURCE	/* for inclusion of strcasecmp() via <string.h> */
46e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <string.h>
483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <time.h>
493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <unistd.h>
50f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#include <sys/types.h>
5164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V#include <libgen.h>
52365857912e27914afa8857af5adf74ee19ca9e03Theodore Ts'o#include <limits.h>
533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
5454c637d4d29af3e6365779f8b12976abe95a4753Theodore Ts'o#include "ext2fs/ext2_fs.h"
553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "ext2fs/ext2fs.h"
563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "et/com_err.h"
571e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o#include "uuid/uuid.h"
583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "e2p/e2p.h"
59dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o#include "jfs_user.h"
6063985320384bf143eaac9857af424800d9867a1aTheodore Ts'o#include "util.h"
61ed1b33e8fb310641684d68a177c940b58f2f529dTheodore Ts'o#include "blkid/blkid.h"
62e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#include "quota/mkquota.h"
633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "../version.h"
65d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o#include "nls-enable.h"
663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
67e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#define QOPT_ENABLE	(1)
68e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#define QOPT_DISABLE	(-1)
69e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
70e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallextern int ask_yn(const char *string, int def);
71e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
72ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'oconst char *program_name = "tune2fs";
73ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'ochar *device_name;
74ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'ochar *new_label, *new_last_mounted, *new_UUID;
75ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'ochar *io_options;
764d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'ostatic int c_flag, C_flag, e_flag, f_flag, g_flag, i_flag, l_flag, L_flag;
77e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic int m_flag, M_flag, Q_flag, r_flag, s_flag = -1, u_flag, U_flag, T_flag;
7864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.Vstatic int I_flag;
79e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic int clear_mmp;
80d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'ostatic time_t last_check_time;
81832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'ostatic int print_label;
8263985320384bf143eaac9857af424800d9867a1aTheodore Ts'ostatic int max_mount_count, mount_count, mount_flags;
83e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic unsigned long interval;
84e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic blk64_t reserved_blocks;
85ce911145ed0fdd1918ee0c80d407c3e778dc64eeAndreas Dilgerstatic double reserved_ratio;
8663985320384bf143eaac9857af424800d9867a1aTheodore Ts'ostatic unsigned long resgid, resuid;
8763985320384bf143eaac9857af424800d9867a1aTheodore Ts'ostatic unsigned short errors;
88832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'ostatic int open_flag;
89832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'ostatic char *features_cmd;
90a0c3fd5e4cdc2e0b032c9ace89d960a622069c32Theodore Ts'ostatic char *mntopts_cmd;
910c17cb25f24730dca138a976a390f105d2191736Theodore Ts'ostatic int stride, stripe_width;
920c17cb25f24730dca138a976a390f105d2191736Theodore Ts'ostatic int stride_set, stripe_width_set;
936cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'ostatic char *extended_cmd;
94721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'ostatic unsigned long new_inode_size;
95e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic char *ext_mount_opts;
96e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic int usrquota, grpquota;
973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
9863985320384bf143eaac9857af424800d9867a1aTheodore Ts'oint journal_size, journal_flags;
9963985320384bf143eaac9857af424800d9867a1aTheodore Ts'ochar *journal_device;
10063985320384bf143eaac9857af424800d9867a1aTheodore Ts'o
10164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.Vstatic struct list_head blk_move_list;
10264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
10364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.Vstruct blk_move {
10464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	struct list_head list;
105e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t old_loc;
106e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t new_loc;
10764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V};
10864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
10964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
11063985320384bf143eaac9857af424800d9867a1aTheodore Ts'ostatic const char *please_fsck = N_("Please run e2fsck on the filesystem.\n");
1111e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o
11214b596d40997c7e55ec8928bd222787f96808a2bTheodore Ts'o#ifdef CONFIG_BUILD_FINDFS
1133e69906495d5898849a6154b0311b5d4a84a27aeTheodore Ts'ovoid do_findfs(int argc, char **argv);
11414b596d40997c7e55ec8928bd222787f96808a2bTheodore Ts'o#endif
1153e69906495d5898849a6154b0311b5d4a84a27aeTheodore Ts'o
116818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'ostatic void usage(void)
1173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
118b21e38a0df0111f527f7b286ff9119534de04c09Theodore Ts'o	fprintf(stderr,
119bb145b01cf5fd27d9afe03c3262d0e1a326e7ec1Theodore Ts'o		_("Usage: %s [-c max_mounts_count] [-e errors_behavior] "
120b21e38a0df0111f527f7b286ff9119534de04c09Theodore Ts'o		  "[-g group]\n"
121ff662d5dbf95f2e68eed6f6b6a4e10307a7d13bdTheodore Ts'o		  "\t[-i interval[d|m|w]] [-j] [-J journal_options] [-l]\n"
122ff662d5dbf95f2e68eed6f6b6a4e10307a7d13bdTheodore Ts'o		  "\t[-m reserved_blocks_percent] "
123e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		  "[-o [^]mount_options[,...]] [-p mmp_update_interval]\n"
124ff662d5dbf95f2e68eed6f6b6a4e10307a7d13bdTheodore Ts'o		  "\t[-r reserved_blocks_count] [-u user] [-C mount_count] "
125ff662d5dbf95f2e68eed6f6b6a4e10307a7d13bdTheodore Ts'o		  "[-L volume_label]\n"
1266cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o		  "\t[-M last_mounted_dir] [-O [^]feature[,...]]\n"
127e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef CONFIG_QUOTA
128e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		  "\t[-Q quota_options]\n"
129e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
1306cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o		  "\t[-E extended-option[,...]] [-T last_check_time] "
13164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		  "[-U UUID]\n\t[ -I new_inode_size ] device\n"), program_name);
132ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o	exit(1);
1333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
1343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
135896938d57e7091e7a032674dfeeb91f2a17fd78bTheodore Ts'ostatic __u32 ok_features[3] = {
136558df54458075856b3a76051648323643a56dadcTheodore Ts'o	/* Compat */
137843049c4dbfe8a0dd4332569eff0ac93529e3324Theodore Ts'o	EXT3_FEATURE_COMPAT_HAS_JOURNAL |
138558df54458075856b3a76051648323643a56dadcTheodore Ts'o		EXT2_FEATURE_COMPAT_DIR_INDEX,
139558df54458075856b3a76051648323643a56dadcTheodore Ts'o	/* Incompat */
140a49670e64e28ac3b15e36cb6bd0a8135d3ecdbbbTheodore Ts'o	EXT2_FEATURE_INCOMPAT_FILETYPE |
141a49670e64e28ac3b15e36cb6bd0a8135d3ecdbbbTheodore Ts'o		EXT3_FEATURE_INCOMPAT_EXTENTS |
142e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		EXT4_FEATURE_INCOMPAT_FLEX_BG |
143e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		EXT4_FEATURE_INCOMPAT_MMP,
144558df54458075856b3a76051648323643a56dadcTheodore Ts'o	/* R/O compat */
145558df54458075856b3a76051648323643a56dadcTheodore Ts'o	EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
1462be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o		EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
1472be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o		EXT4_FEATURE_RO_COMPAT_DIR_NLINK|
1482be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o		EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|
1494e988cb4c16046c8c56dc3d76beb41466a966d81Jose R. Santos		EXT4_FEATURE_RO_COMPAT_GDT_CSUM |
150e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef CONFIG_QUOTA
151e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		EXT4_FEATURE_RO_COMPAT_QUOTA |
152e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
1530f8186598ccb0c5e8666b6efe7178c69e73d81b6Theodore Ts'o		EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
154896938d57e7091e7a032674dfeeb91f2a17fd78bTheodore Ts'o};
155896938d57e7091e7a032674dfeeb91f2a17fd78bTheodore Ts'o
1567c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'ostatic __u32 clear_ok_features[3] = {
157558df54458075856b3a76051648323643a56dadcTheodore Ts'o	/* Compat */
1587c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o	EXT3_FEATURE_COMPAT_HAS_JOURNAL |
159037914e28f69110020195fe9f9ea56e5274ff2c0Theodore Ts'o		EXT2_FEATURE_COMPAT_RESIZE_INODE |
160558df54458075856b3a76051648323643a56dadcTheodore Ts'o		EXT2_FEATURE_COMPAT_DIR_INDEX,
161558df54458075856b3a76051648323643a56dadcTheodore Ts'o	/* Incompat */
162a49670e64e28ac3b15e36cb6bd0a8135d3ecdbbbTheodore Ts'o	EXT2_FEATURE_INCOMPAT_FILETYPE |
163e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		EXT4_FEATURE_INCOMPAT_FLEX_BG |
164e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		EXT4_FEATURE_INCOMPAT_MMP,
165558df54458075856b3a76051648323643a56dadcTheodore Ts'o	/* R/O compat */
1664e988cb4c16046c8c56dc3d76beb41466a966d81Jose R. Santos	EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
1672be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o		EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
1682be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o		EXT4_FEATURE_RO_COMPAT_DIR_NLINK|
1692be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o		EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|
170e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef CONFIG_QUOTA
171e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		EXT4_FEATURE_RO_COMPAT_QUOTA |
172e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
1730f8186598ccb0c5e8666b6efe7178c69e73d81b6Theodore Ts'o		EXT4_FEATURE_RO_COMPAT_GDT_CSUM
174896938d57e7091e7a032674dfeeb91f2a17fd78bTheodore Ts'o};
175896938d57e7091e7a032674dfeeb91f2a17fd78bTheodore Ts'o
17663985320384bf143eaac9857af424800d9867a1aTheodore Ts'o/*
177dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o * Remove an external journal from the filesystem
178dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o */
179e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic int remove_journal_device(ext2_filsys fs)
180dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o{
1814ea7bd04390935e1f8b473c8b857e518df2e226bTheodore Ts'o	char		*journal_path;
182dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	ext2_filsys	jfs;
183dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	char		buf[1024];
184dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	journal_superblock_t	*jsb;
185dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	int		i, nr_users;
186dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	errcode_t	retval;
1874d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o	int		commit_remove_journal = 0;
1882a29f1354f793557fa1829c9e85e74586e2907dbTheodore Ts'o	io_manager	io_ptr;
1894d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o
1904d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o	if (f_flag)
1914d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o		commit_remove_journal = 1; /* force removal even if error */
192dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o
1932d15576dfe8ffd8521a6f4211cef3d2a663dc379Andreas Dilger	uuid_unparse(fs->super->s_journal_uuid, buf);
194ed1b33e8fb310641684d68a177c940b58f2f529dTheodore Ts'o	journal_path = blkid_get_devname(NULL, "UUID", buf);
1952d15576dfe8ffd8521a6f4211cef3d2a663dc379Andreas Dilger
1964ea7bd04390935e1f8b473c8b857e518df2e226bTheodore Ts'o	if (!journal_path) {
1974ea7bd04390935e1f8b473c8b857e518df2e226bTheodore Ts'o		journal_path =
1982d15576dfe8ffd8521a6f4211cef3d2a663dc379Andreas Dilger			ext2fs_find_block_device(fs->super->s_journal_dev);
1994ea7bd04390935e1f8b473c8b857e518df2e226bTheodore Ts'o		if (!journal_path)
200e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goto no_valid_journal;
2012d15576dfe8ffd8521a6f4211cef3d2a663dc379Andreas Dilger	}
202dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o
2032a29f1354f793557fa1829c9e85e74586e2907dbTheodore Ts'o#ifdef CONFIG_TESTIO_DEBUG
204f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o	if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
205f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o		io_ptr = test_io_manager;
206f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o		test_io_backing_manager = unix_io_manager;
207f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o	} else
2082a29f1354f793557fa1829c9e85e74586e2907dbTheodore Ts'o#endif
209f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o		io_ptr = unix_io_manager;
2104ea7bd04390935e1f8b473c8b857e518df2e226bTheodore Ts'o	retval = ext2fs_open(journal_path, EXT2_FLAG_RW|
211dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o			     EXT2_FLAG_JOURNAL_DEV_OK, 0,
2122a29f1354f793557fa1829c9e85e74586e2907dbTheodore Ts'o			     fs->blocksize, io_ptr, &jfs);
213dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	if (retval) {
214e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		com_err(program_name, retval, "%s",
215dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o			_("while trying to open external journal"));
2164d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o		goto no_valid_journal;
217dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	}
218e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!(jfs->super->s_feature_incompat &
219e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	      EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
2207141b54b1af506a9a5fdf4aed649eb6526bad706Theodore Ts'o		fprintf(stderr, _("%s is not a journal device.\n"),
2214ea7bd04390935e1f8b473c8b857e518df2e226bTheodore Ts'o			journal_path);
2224d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o		goto no_valid_journal;
223dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	}
224dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o
225dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	/* Get the journal superblock */
226e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if ((retval = io_channel_read_blk64(jfs->io, 1, -1024, buf))) {
227e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		com_err(program_name, retval, "%s",
228dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o			_("while reading journal superblock"));
2294d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o		goto no_valid_journal;
230dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	}
231dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o
232dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	jsb = (journal_superblock_t *) buf;
233e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if ((jsb->s_header.h_magic != (unsigned)ntohl(JFS_MAGIC_NUMBER)) ||
234e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	    (jsb->s_header.h_blocktype != (unsigned)ntohl(JFS_SUPERBLOCK_V2))) {
235544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		fputs(_("Journal superblock not found!\n"), stderr);
2364d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o		goto no_valid_journal;
237dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	}
238dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o
239dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	/* Find the filesystem UUID */
240dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	nr_users = ntohl(jsb->s_nr_users);
241ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o	for (i = 0; i < nr_users; i++) {
242e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (memcmp(fs->super->s_uuid, &jsb->s_users[i * 16], 16) == 0)
243dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o			break;
244dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	}
245dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	if (i >= nr_users) {
246efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		fputs(_("Filesystem's UUID not found on journal device.\n"),
247544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		      stderr);
2484d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o		commit_remove_journal = 1;
2494d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o		goto no_valid_journal;
250dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	}
251dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	nr_users--;
252ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o	for (i = 0; i < nr_users; i++)
253e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		memcpy(&jsb->s_users[i * 16], &jsb->s_users[(i + 1) * 16], 16);
254dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	jsb->s_nr_users = htonl(nr_users);
255dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o
256dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	/* Write back the journal superblock */
257e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if ((retval = io_channel_write_blk64(jfs->io, 1, -1024, buf))) {
258dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o		com_err(program_name, retval,
259dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o			"while writing journal superblock.");
2604d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o		goto no_valid_journal;
261dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	}
262dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o
2634d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o	commit_remove_journal = 1;
2644d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o
2654d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'ono_valid_journal:
2664d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o	if (commit_remove_journal == 0) {
267e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		fputs(_("Cannot locate journal device. It was NOT removed\n"
268e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			"Use -f option to remove missing journal device.\n"),
269e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		      stderr);
270e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return 1;
2714d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o	}
272dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	fs->super->s_journal_dev = 0;
273ed1b33e8fb310641684d68a177c940b58f2f529dTheodore Ts'o	uuid_clear(fs->super->s_journal_uuid);
274dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o	ext2fs_mark_super_dirty(fs);
275544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o	fputs(_("Journal removed\n"), stdout);
2764ea7bd04390935e1f8b473c8b857e518df2e226bTheodore Ts'o	free(journal_path);
277e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
278e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return 0;
279dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o}
280dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o
281194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o/* Helper function for remove_journal_inode */
282e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic int release_blocks_proc(ext2_filsys fs, blk64_t *blocknr,
283e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			       e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
284e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			       blk64_t ref_block EXT2FS_ATTR((unused)),
285e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			       int ref_offset EXT2FS_ATTR((unused)),
286544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o			       void *private EXT2FS_ATTR((unused)))
287194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o{
288e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t	block;
289194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o	int	group;
290194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o
291194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o	block = *blocknr;
292e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	ext2fs_unmark_block_bitmap2(fs->block_map, block);
293e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	group = ext2fs_group_of_blk2(fs, block);
294e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	ext2fs_bg_free_blocks_count_set(fs, group, ext2fs_bg_free_blocks_count(fs, group) + 1);
2954e988cb4c16046c8c56dc3d76beb41466a966d81Jose R. Santos	ext2fs_group_desc_csum_set(fs, group);
296e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	ext2fs_free_blocks_count_add(fs->super, EXT2FS_CLUSTER_RATIO(fs));
297194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o	return 0;
298194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o}
299194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o
300194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o/*
301194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o * Remove the journal inode from the filesystem
302194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o */
303e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic errcode_t remove_journal_inode(ext2_filsys fs)
304194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o{
305194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o	struct ext2_inode	inode;
306194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o	errcode_t		retval;
307194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o	ino_t			ino = fs->super->s_journal_inum;
308efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
309194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o	retval = ext2fs_read_inode(fs, ino,  &inode);
310194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o	if (retval) {
311e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		com_err(program_name, retval, "%s",
312194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o			_("while reading journal inode"));
313e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return retval;
314194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o	}
315194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o	if (ino == EXT2_JOURNAL_INO) {
316194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o		retval = ext2fs_read_bitmaps(fs);
317194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o		if (retval) {
318e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			com_err(program_name, retval, "%s",
319194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o				_("while reading bitmaps"));
320e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return retval;
321194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o		}
322e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		retval = ext2fs_block_iterate3(fs, ino,
323e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					       BLOCK_FLAG_READ_ONLY, NULL,
324e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					       release_blocks_proc, NULL);
325194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o		if (retval) {
326e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			com_err(program_name, retval, "%s",
327194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o				_("while clearing journal inode"));
328e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return retval;
329194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o		}
330194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o		memset(&inode, 0, sizeof(inode));
331194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o		ext2fs_mark_bb_dirty(fs);
332194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o		fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
333194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o	} else
334194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o		inode.i_flags &= ~EXT2_IMMUTABLE_FL;
335194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o	retval = ext2fs_write_inode(fs, ino, &inode);
336194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o	if (retval) {
337e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		com_err(program_name, retval, "%s",
338194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o			_("while writing journal inode"));
339e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return retval;
340194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o	}
341194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o	fs->super->s_journal_inum = 0;
342194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o	ext2fs_mark_super_dirty(fs);
343e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
344e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return 0;
345194686bbae9da1259035693d7449d7662720b19bTheodore Ts'o}
346dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o
347dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o/*
348a0c3fd5e4cdc2e0b032c9ace89d960a622069c32Theodore Ts'o * Update the default mount options
349a0c3fd5e4cdc2e0b032c9ace89d960a622069c32Theodore Ts'o */
350e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic int update_mntopts(ext2_filsys fs, char *mntopts)
351a0c3fd5e4cdc2e0b032c9ace89d960a622069c32Theodore Ts'o{
352ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o	struct ext2_super_block *sb = fs->super;
353a0c3fd5e4cdc2e0b032c9ace89d960a622069c32Theodore Ts'o
354a0c3fd5e4cdc2e0b032c9ace89d960a622069c32Theodore Ts'o	if (e2p_edit_mntopts(mntopts, &sb->s_default_mount_opts, ~0)) {
355a0c3fd5e4cdc2e0b032c9ace89d960a622069c32Theodore Ts'o		fprintf(stderr, _("Invalid mount option set: %s\n"),
356a0c3fd5e4cdc2e0b032c9ace89d960a622069c32Theodore Ts'o			mntopts);
357e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return 1;
358a0c3fd5e4cdc2e0b032c9ace89d960a622069c32Theodore Ts'o	}
359a0c3fd5e4cdc2e0b032c9ace89d960a622069c32Theodore Ts'o	ext2fs_mark_super_dirty(fs);
360e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
361e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return 0;
362e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
363e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
364e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic int check_fsck_needed(ext2_filsys fs)
365e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
366e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (fs->super->s_state & EXT2_VALID_FS)
367e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return 0;
368e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	printf("\n%s\n", _(please_fsck));
369e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (mount_flags & EXT2_MF_READONLY)
370e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		printf(_("(and reboot afterwards!)\n"));
371e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return 1;
37266457fcb842300e757a69c49c2eb4d8e335be34cDarrick J. Wong}
37366457fcb842300e757a69c49c2eb4d8e335be34cDarrick J. Wong
374079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'ostatic void request_fsck_afterwards(ext2_filsys fs)
375079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o{
376079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o	static int requested = 0;
377079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o
378079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o	if (requested++)
379079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o		return;
380079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o	fs->super->s_state &= ~EXT2_VALID_FS;
381079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o	printf("\n%s\n", _(please_fsck));
382079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o	if (mount_flags & EXT2_MF_READONLY)
383e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		printf("%s", _("(and reboot afterwards!)\n"));
384079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o}
385079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o
386a0c3fd5e4cdc2e0b032c9ace89d960a622069c32Theodore Ts'o/*
38763985320384bf143eaac9857af424800d9867a1aTheodore Ts'o * Update the feature set as provided by the user.
38863985320384bf143eaac9857af424800d9867a1aTheodore Ts'o */
389e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic int update_feature_set(ext2_filsys fs, char *features)
39063985320384bf143eaac9857af424800d9867a1aTheodore Ts'o{
391ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o	struct ext2_super_block *sb = fs->super;
392079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o	struct ext2_group_desc *gd;
393885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o	__u32		old_features[3];
394e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	dgrp_t		i;
395e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	int		type_err;
3967c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o	unsigned int	mask_err;
3972eb3b20e808e360f59d58ced7e833836b652648fTheodore Ts'o
398885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o#define FEATURE_ON(type, mask) (!(old_features[(type)] & (mask)) && \
399885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o				((&sb->s_feature_compat)[(type)] & (mask)))
400885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o#define FEATURE_OFF(type, mask) ((old_features[(type)] & (mask)) && \
401885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o				 !((&sb->s_feature_compat)[(type)] & (mask)))
402885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o#define FEATURE_CHANGED(type, mask) ((mask) & \
403885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o		     (old_features[(type)] ^ (&sb->s_feature_compat)[(type)]))
404885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o
405885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o	old_features[E2P_FEATURE_COMPAT] = sb->s_feature_compat;
406885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o	old_features[E2P_FEATURE_INCOMPAT] = sb->s_feature_incompat;
407885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o	old_features[E2P_FEATURE_RO_INCOMPAT] = sb->s_feature_ro_compat;
408885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o
4097c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o	if (e2p_edit_feature2(features, &sb->s_feature_compat,
4107c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o			      ok_features, clear_ok_features,
4117c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o			      &type_err, &mask_err)) {
4127c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o		if (!mask_err)
4137c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o			fprintf(stderr,
4147c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o				_("Invalid filesystem option set: %s\n"),
4157c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o				features);
4167c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o		else if (type_err & E2P_FEATURE_NEGATE_FLAG)
4177c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o			fprintf(stderr, _("Clearing filesystem feature '%s' "
4187c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o					  "not supported.\n"),
4197c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o				e2p_feature2string(type_err &
4207c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o						   E2P_FEATURE_TYPE_MASK,
4217c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o						   mask_err));
4227c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o		else
4237c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o			fprintf(stderr, _("Setting filesystem feature '%s' "
4247c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o					  "not supported.\n"),
4257c4a2ef5946a52b9efa70b110d5abcf8f4fb6abeTheodore Ts'o				e2p_feature2string(type_err, mask_err));
426e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return 1;
42763985320384bf143eaac9857af424800d9867a1aTheodore Ts'o	}
428885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o
429885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o	if (FEATURE_OFF(E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
43063985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		if ((mount_flags & EXT2_MF_MOUNTED) &&
43163985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		    !(mount_flags & EXT2_MF_READONLY)) {
4322be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o			fputs(_("The has_journal feature may only be "
433544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o				"cleared when the filesystem is\n"
434544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o				"unmounted or mounted "
435544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o				"read-only.\n"), stderr);
436e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return 1;
43763985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		}
43863985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		if (sb->s_feature_incompat &
43963985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		    EXT3_FEATURE_INCOMPAT_RECOVER) {
440544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o			fputs(_("The needs_recovery flag is set.  "
441544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o				"Please run e2fsck before clearing\n"
442544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o				"the has_journal flag.\n"), stderr);
443e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return 1;
44463985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		}
44563985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		if (sb->s_journal_inum) {
446e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			if (remove_journal_inode(fs))
447e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				return 1;
44863985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		}
449de49f015a4585900ca40e291f9b9a827714f0d8fTheodore Ts'o		if (sb->s_journal_dev) {
450e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			if (remove_journal_device(fs))
451e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				return 1;
452de49f015a4585900ca40e291f9b9a827714f0d8fTheodore Ts'o		}
45363985320384bf143eaac9857af424800d9867a1aTheodore Ts'o	}
454e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (FEATURE_ON(E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_MMP)) {
455e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		int error;
456e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
457e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if ((mount_flags & EXT2_MF_MOUNTED) ||
458e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		    (mount_flags & EXT2_MF_READONLY)) {
459e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			fputs(_("The multiple mount protection feature can't\n"
460e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				"be set if the filesystem is mounted or\n"
461e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				"read-only.\n"), stderr);
462e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return 1;
463e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
464e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
465e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		error = ext2fs_mmp_init(fs);
466e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (error) {
467e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			fputs(_("\nError while enabling multiple mount "
468e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				"protection feature."), stderr);
469e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return 1;
470e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
471e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
472e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		/*
473e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		 * We want to update group desc with the new free blocks count
474e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		 */
475e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
476e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
477e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		printf(_("Multiple mount protection has been enabled "
478e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			 "with update interval %ds.\n"),
479e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		       sb->s_mmp_update_interval);
480e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
481e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
482e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (FEATURE_OFF(E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_MMP)) {
483e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		int error;
484e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
485e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (mount_flags & EXT2_MF_READONLY) {
486e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			fputs(_("The multiple mount protection feature cannot\n"
487e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				"be disabled if the filesystem is readonly.\n"),
488e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				stderr);
489e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return 1;
490e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
491e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
492e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		error = ext2fs_read_bitmaps(fs);
493e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (error) {
494e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			fputs(_("Error while reading bitmaps\n"), stderr);
495e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return 1;
496e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
497e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
498e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		error = ext2fs_mmp_read(fs, sb->s_mmp_block, NULL);
499e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (error) {
500e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			struct mmp_struct *mmp_cmp = fs->mmp_cmp;
501e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
502e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			if (error == EXT2_ET_MMP_MAGIC_INVALID)
503e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				printf(_("Magic number in MMP block does not "
504e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					 "match. expected: %x, actual: %x\n"),
505e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					 EXT4_MMP_MAGIC, mmp_cmp->mmp_magic);
506e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			else
507e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				com_err(program_name, error, "%s",
508e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					_("while reading MMP block."));
509e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goto mmp_error;
510e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
511e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
512e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		/* We need to force out the group descriptors as well */
513e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
514e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_block_alloc_stats2(fs, sb->s_mmp_block, -1);
515e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallmmp_error:
516e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		sb->s_mmp_block = 0;
517e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		sb->s_mmp_update_interval = 0;
518e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
519885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o
520885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o	if (FEATURE_ON(E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
52163985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		/*
52263985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		 * If adding a journal flag, let the create journal
5237a0516a385d87a508843b21a1932b689697d9ffaBenno Schulenberg		 * code below handle setting the flag and creating the
5247a0516a385d87a508843b21a1932b689697d9ffaBenno Schulenberg		 * journal.  We supply a default size if necessary.
52563985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		 */
526dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o		if (!journal_size)
527dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o			journal_size = -1;
52808dd830ddd99b43396bec4401b6badf4498f46d0Theodore Ts'o		sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
52963985320384bf143eaac9857af424800d9867a1aTheodore Ts'o	}
530885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o
531885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o	if (FEATURE_ON(E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_INDEX)) {
532843049c4dbfe8a0dd4332569eff0ac93529e3324Theodore Ts'o		if (!sb->s_def_hash_version)
533d1070d91b4de8438dc78c034283baaa19b31d25eTheodore Ts'o			sb->s_def_hash_version = EXT2_HASH_HALF_MD4;
534843049c4dbfe8a0dd4332569eff0ac93529e3324Theodore Ts'o		if (uuid_is_null((unsigned char *) sb->s_hash_seed))
535843049c4dbfe8a0dd4332569eff0ac93529e3324Theodore Ts'o			uuid_generate((unsigned char *) sb->s_hash_seed);
536843049c4dbfe8a0dd4332569eff0ac93529e3324Theodore Ts'o	}
537dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o
538a49670e64e28ac3b15e36cb6bd0a8135d3ecdbbbTheodore Ts'o	if (FEATURE_OFF(E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
539c2d4300b8a4a13d8a78b86c386f76259f23feec2Jose R. Santos		if (ext2fs_check_desc(fs)) {
540c2d4300b8a4a13d8a78b86c386f76259f23feec2Jose R. Santos			fputs(_("Clearing the flex_bg flag would "
541c2d4300b8a4a13d8a78b86c386f76259f23feec2Jose R. Santos				"cause the the filesystem to be\n"
542c2d4300b8a4a13d8a78b86c386f76259f23feec2Jose R. Santos				"inconsistent.\n"), stderr);
543e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return 1;
544c2d4300b8a4a13d8a78b86c386f76259f23feec2Jose R. Santos		}
545c2d4300b8a4a13d8a78b86c386f76259f23feec2Jose R. Santos	}
546dc2ec525f5619bf478d2aae1b406fca2ff4b0d21Theodore Ts'o
5472be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o	if (FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT,
5482be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o			    EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
5492be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o		if ((mount_flags & EXT2_MF_MOUNTED) &&
5502be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o		    !(mount_flags & EXT2_MF_READONLY)) {
5512be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o			fputs(_("The huge_file feature may only be "
5522be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o				"cleared when the filesystem is\n"
5532be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o				"unmounted or mounted "
5542be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o				"read-only.\n"), stderr);
555e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return 1;
5562be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o		}
5572be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o	}
5582be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o
559079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o	if (FEATURE_ON(E2P_FEATURE_RO_INCOMPAT,
560079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o		       EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
561e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		for (i = 0; i < fs->group_desc_count; i++) {
562e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			gd = ext2fs_group_desc(fs, fs->group_desc, i);
563079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o			gd->bg_itable_unused = 0;
564079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o			gd->bg_flags = EXT2_BG_INODE_ZEROED;
565079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o			ext2fs_group_desc_csum_set(fs, i);
566079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o		}
567079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o		fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
568079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o	}
569079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o
570079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o	if (FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT,
571079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o			EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
572e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		for (i = 0; i < fs->group_desc_count; i++) {
573e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			gd = ext2fs_group_desc(fs, fs->group_desc, i);
574079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o			if ((gd->bg_flags & EXT2_BG_INODE_ZEROED) == 0) {
575079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o				/*
576079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o				 * XXX what we really should do is zap
577079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o				 * uninitialized inode tables instead.
578079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o				 */
579079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o				request_fsck_afterwards(fs);
580079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o				break;
581079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o			}
582079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o			gd->bg_itable_unused = 0;
583079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o			gd->bg_flags = 0;
584079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o			gd->bg_checksum = 0;
585079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o		}
586079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o		fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
587079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o	}
588079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o
589e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (FEATURE_ON(E2P_FEATURE_RO_INCOMPAT,
590e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				EXT4_FEATURE_RO_COMPAT_QUOTA)) {
591e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		/*
592e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		 * Set the Q_flag here and handle the quota options in the code
593e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		 * below.
594e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		 */
595e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (!Q_flag) {
596e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			Q_flag = 1;
597e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			/* Enable both user quota and group quota by default */
598e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			usrquota = QOPT_ENABLE;
599e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			grpquota = QOPT_ENABLE;
600e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
601e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		sb->s_feature_ro_compat &= ~EXT4_FEATURE_RO_COMPAT_QUOTA;
602e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
603e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
604e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT,
605e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				EXT4_FEATURE_RO_COMPAT_QUOTA)) {
606e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		/*
607e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		 * Set the Q_flag here and handle the quota options in the code
608e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		 * below.
609e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		 */
610e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (Q_flag)
611e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			fputs(_("\nWarning: '^quota' option overrides '-Q'"
612e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				"arguments.\n"), stderr);
613e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		Q_flag = 1;
614e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		/* Disable both user quota and group quota by default */
615e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		usrquota = QOPT_DISABLE;
616e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		grpquota = QOPT_DISABLE;
617e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
618e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
61963985320384bf143eaac9857af424800d9867a1aTheodore Ts'o	if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
62063985320384bf143eaac9857af424800d9867a1aTheodore Ts'o	    (sb->s_feature_compat || sb->s_feature_ro_compat ||
62163985320384bf143eaac9857af424800d9867a1aTheodore Ts'o	     sb->s_feature_incompat))
62263985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		ext2fs_update_dynamic_rev(fs);
623885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o
624885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o	if (FEATURE_CHANGED(E2P_FEATURE_RO_INCOMPAT,
625885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o			    EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) ||
6262be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o	    FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT,
6272be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o			EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ||
628885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o	    FEATURE_CHANGED(E2P_FEATURE_INCOMPAT,
629037914e28f69110020195fe9f9ea56e5274ff2c0Theodore Ts'o			    EXT2_FEATURE_INCOMPAT_FILETYPE) ||
630037914e28f69110020195fe9f9ea56e5274ff2c0Theodore Ts'o	    FEATURE_CHANGED(E2P_FEATURE_COMPAT,
631558df54458075856b3a76051648323643a56dadcTheodore Ts'o			    EXT2_FEATURE_COMPAT_RESIZE_INODE) ||
632558df54458075856b3a76051648323643a56dadcTheodore Ts'o	    FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT,
633079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o			EXT2_FEATURE_RO_COMPAT_LARGE_FILE))
634079ad63d59a0b4c9bc3242117ce9b3d97d9dd711Theodore Ts'o		request_fsck_afterwards(fs);
635885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o
636885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o	if ((old_features[E2P_FEATURE_COMPAT] != sb->s_feature_compat) ||
637885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o	    (old_features[E2P_FEATURE_INCOMPAT] != sb->s_feature_incompat) ||
638885bf6b83252672eb2e9bd2fb6fd45a1978b0661Theodore Ts'o	    (old_features[E2P_FEATURE_RO_INCOMPAT] != sb->s_feature_ro_compat))
6392eb3b20e808e360f59d58ced7e833836b652648fTheodore Ts'o		ext2fs_mark_super_dirty(fs);
640e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
641e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return 0;
64263985320384bf143eaac9857af424800d9867a1aTheodore Ts'o}
64363985320384bf143eaac9857af424800d9867a1aTheodore Ts'o
64463985320384bf143eaac9857af424800d9867a1aTheodore Ts'o/*
64563985320384bf143eaac9857af424800d9867a1aTheodore Ts'o * Add a journal to the filesystem.
64663985320384bf143eaac9857af424800d9867a1aTheodore Ts'o */
647e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic int add_journal(ext2_filsys fs)
64863985320384bf143eaac9857af424800d9867a1aTheodore Ts'o{
64963985320384bf143eaac9857af424800d9867a1aTheodore Ts'o	unsigned long journal_blocks;
65063985320384bf143eaac9857af424800d9867a1aTheodore Ts'o	errcode_t	retval;
65116ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o	ext2_filsys	jfs;
6522a29f1354f793557fa1829c9e85e74586e2907dbTheodore Ts'o	io_manager	io_ptr;
65363985320384bf143eaac9857af424800d9867a1aTheodore Ts'o
65463985320384bf143eaac9857af424800d9867a1aTheodore Ts'o	if (fs->super->s_feature_compat &
65563985320384bf143eaac9857af424800d9867a1aTheodore Ts'o	    EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
656544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		fputs(_("The filesystem already has a journal.\n"), stderr);
6572d15576dfe8ffd8521a6f4211cef3d2a663dc379Andreas Dilger		goto err;
65863985320384bf143eaac9857af424800d9867a1aTheodore Ts'o	}
65963985320384bf143eaac9857af424800d9867a1aTheodore Ts'o	if (journal_device) {
66063985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		check_plausibility(journal_device);
66163985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		check_mount(journal_device, 0, _("journal"));
6622a29f1354f793557fa1829c9e85e74586e2907dbTheodore Ts'o#ifdef CONFIG_TESTIO_DEBUG
663f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o		if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
664f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o			io_ptr = test_io_manager;
665f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o			test_io_backing_manager = unix_io_manager;
666f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o		} else
6672a29f1354f793557fa1829c9e85e74586e2907dbTheodore Ts'o#endif
668f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o			io_ptr = unix_io_manager;
66916ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o		retval = ext2fs_open(journal_device, EXT2_FLAG_RW|
67016ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o				     EXT2_FLAG_JOURNAL_DEV_OK, 0,
6712a29f1354f793557fa1829c9e85e74586e2907dbTheodore Ts'o				     fs->blocksize, io_ptr, &jfs);
67216ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o		if (retval) {
67316ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o			com_err(program_name, retval,
6741d08d9bfc225543eaf12bee7cf655124f66f43e4Theodore Ts'o				_("\n\twhile trying to open journal on %s\n"),
67516ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o				journal_device);
6762d15576dfe8ffd8521a6f4211cef3d2a663dc379Andreas Dilger			goto err;
67716ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o		}
67863985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		printf(_("Creating journal on device %s: "),
67963985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		       journal_device);
6804055ef7301ddf93120eb174f3473be15ce5a658bTheodore Ts'o		fflush(stdout);
6812d15576dfe8ffd8521a6f4211cef3d2a663dc379Andreas Dilger
68216ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o		retval = ext2fs_add_journal_device(fs, jfs);
6832d15576dfe8ffd8521a6f4211cef3d2a663dc379Andreas Dilger		ext2fs_close(jfs);
68463985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		if (retval) {
685ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			com_err(program_name, retval,
686ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				_("while adding filesystem to journal on %s"),
687ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				journal_device);
6882d15576dfe8ffd8521a6f4211cef3d2a663dc379Andreas Dilger			goto err;
68963985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		}
690544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		fputs(_("done\n"), stdout);
69163985320384bf143eaac9857af424800d9867a1aTheodore Ts'o	} else if (journal_size) {
692544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		fputs(_("Creating journal inode: "), stdout);
69363985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		fflush(stdout);
6942537b6d0c1aa9710a05cdfafc281b4884c67bdb2Theodore Ts'o		journal_blocks = figure_journal_size(journal_size, fs);
6952537b6d0c1aa9710a05cdfafc281b4884c67bdb2Theodore Ts'o
69663985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		retval = ext2fs_add_journal_inode(fs, journal_blocks,
69763985320384bf143eaac9857af424800d9867a1aTheodore Ts'o						  journal_flags);
69863985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		if (retval) {
6997141b54b1af506a9a5fdf4aed649eb6526bad706Theodore Ts'o			fprintf(stderr, "\n");
700e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			com_err(program_name, retval, "%s",
7011d08d9bfc225543eaf12bee7cf655124f66f43e4Theodore Ts'o				_("\n\twhile trying to create journal file"));
702e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return retval;
7031d08d9bfc225543eaf12bee7cf655124f66f43e4Theodore Ts'o		} else
704544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o			fputs(_("done\n"), stdout);
70563985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		/*
70663985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		 * If the filesystem wasn't mounted, we need to force
70763985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		 * the block group descriptors out.
70863985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		 */
70963985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		if ((mount_flags & EXT2_MF_MOUNTED) == 0)
71063985320384bf143eaac9857af424800d9867a1aTheodore Ts'o			fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
71163985320384bf143eaac9857af424800d9867a1aTheodore Ts'o	}
712e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	print_check_message(fs->super->s_max_mnt_count,
713e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			    fs->super->s_checkinterval);
714e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return 0;
7152d15576dfe8ffd8521a6f4211cef3d2a663dc379Andreas Dilger
7162d15576dfe8ffd8521a6f4211cef3d2a663dc379Andreas Dilgererr:
71745e338f5332a54295893dba2e32cc093d1316f60Jim Meyering	free(journal_device);
718e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return 1;
719e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
720e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
721e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic void handle_quota_options(ext2_filsys fs)
722e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
723e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	quota_ctx_t qctx;
724e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	ext2_ino_t qf_ino;
725e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
726e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!usrquota && !grpquota)
727e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		/* Nothing to do. */
728e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return;
729e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
730e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	quota_init_context(&qctx, fs, -1);
731e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
732e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (usrquota == QOPT_ENABLE || grpquota == QOPT_ENABLE)
733e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		quota_compute_usage(qctx);
734e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
735e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (usrquota == QOPT_ENABLE && !fs->super->s_usr_quota_inum) {
736e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if ((qf_ino = quota_file_exists(fs, USRQUOTA,
737e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall						QFMT_VFS_V1)) > 0)
738e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			quota_update_limits(qctx, qf_ino, USRQUOTA);
739e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		quota_write_inode(qctx, USRQUOTA);
740e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	} else if (usrquota == QOPT_DISABLE) {
741e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		quota_remove_inode(fs, USRQUOTA);
742e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
743e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
744e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (grpquota == QOPT_ENABLE && !fs->super->s_grp_quota_inum) {
745e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if ((qf_ino = quota_file_exists(fs, GRPQUOTA,
746e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall						QFMT_VFS_V1)) > 0)
747e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			quota_update_limits(qctx, qf_ino, GRPQUOTA);
748e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		quota_write_inode(qctx, GRPQUOTA);
749e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	} else if (grpquota == QOPT_DISABLE) {
750e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		quota_remove_inode(fs, GRPQUOTA);
751e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
752e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
753e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	quota_release_context(&qctx);
754e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
755e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if ((usrquota == QOPT_ENABLE) || (grpquota == QOPT_ENABLE)) {
756e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		fprintf(stderr, "%s", _("\nWarning: the quota feature is still "
757e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				  "under development\n"
758e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				  "See https://ext4.wiki.kernel.org/"
759e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				  "index.php/Quota for more information\n\n"));
760e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		fs->super->s_feature_ro_compat |= EXT4_FEATURE_RO_COMPAT_QUOTA;
761e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_mark_super_dirty(fs);
762e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	} else if (!fs->super->s_usr_quota_inum &&
763e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		   !fs->super->s_grp_quota_inum) {
764e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		fs->super->s_feature_ro_compat &= ~EXT4_FEATURE_RO_COMPAT_QUOTA;
765e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_mark_super_dirty(fs);
766e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
767e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
768e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return;
769771e8db9f04da550ee7c0ca74b198e989ea4ff35Aditya Kali}
770771e8db9f04da550ee7c0ca74b198e989ea4ff35Aditya Kali
771e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef CONFIG_QUOTA
772e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic void parse_quota_opts(const char *opts)
773e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
774e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	char	*buf, *token, *next, *p;
775e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	int	len;
776e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
777e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	len = strlen(opts);
778e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	buf = malloc(len+1);
779e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!buf) {
780e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		fputs(_("Couldn't allocate memory to parse quota "
781e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			"options!\n"), stderr);
782e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		exit(1);
783e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
784e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	strcpy(buf, opts);
785e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	for (token = buf; token && *token; token = next) {
786e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		p = strchr(token, ',');
787e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		next = 0;
788e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (p) {
789e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			*p = 0;
790e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			next = p+1;
791e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
792e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
793e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (strcmp(token, "usrquota") == 0) {
794e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			usrquota = QOPT_ENABLE;
795e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		} else if (strcmp(token, "^usrquota") == 0) {
796e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			usrquota = QOPT_DISABLE;
797e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		} else if (strcmp(token, "grpquota") == 0) {
798e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			grpquota = QOPT_ENABLE;
799e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		} else if (strcmp(token, "^grpquota") == 0) {
800e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			grpquota = QOPT_DISABLE;
801e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		} else {
802e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			fputs(_("\nBad quota options specified.\n\n"
803e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				"Following valid quota options are available "
804e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				"(pass by separating with comma):\n"
805e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				"\t[^]usrquota\n"
806e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				"\t[^]grpquota\n"
807e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				"\n\n"), stderr);
808e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			free(buf);
809e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			exit(1);
810e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
811e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
812e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	free(buf);
813e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
814e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
815832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o
816c8c071a07319939dfd7ae2ff1dedec644d750debTheodore Ts'ostatic void parse_e2label_options(int argc, char ** argv)
817832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o{
818832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o	if ((argc < 2) || (argc > 3)) {
819544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		fputs(_("Usage: e2label device [newlabel]\n"), stderr);
820832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o		exit(1);
821832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o	}
8222e8ca9a26b0bd7dae546a3f9a98df67b043fe3beTheodore Ts'o	io_options = strchr(argv[1], '?');
8232e8ca9a26b0bd7dae546a3f9a98df67b043fe3beTheodore Ts'o	if (io_options)
8242e8ca9a26b0bd7dae546a3f9a98df67b043fe3beTheodore Ts'o		*io_options++ = 0;
825332f2c23821a17808b2566a7200b286ba9bc855aTheodore Ts'o	device_name = blkid_get_devname(NULL, argv[1], NULL);
826817e49e3ce0a70252113438440fc12607140d032Theodore Ts'o	if (!device_name) {
827efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		com_err("e2label", 0, _("Unable to resolve '%s'"),
828817e49e3ce0a70252113438440fc12607140d032Theodore Ts'o			argv[1]);
829817e49e3ce0a70252113438440fc12607140d032Theodore Ts'o		exit(1);
830817e49e3ce0a70252113438440fc12607140d032Theodore Ts'o	}
8312be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o	open_flag = EXT2_FLAG_JOURNAL_DEV_OK;
832832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o	if (argc == 3) {
8330ddfd9a529d2d33f9c5b59fd7409b716e50d45b2Theodore Ts'o		open_flag |= EXT2_FLAG_RW;
834832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o		L_flag = 1;
835832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o		new_label = argv[2];
836efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o	} else
837832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o		print_label++;
838832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o}
839832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o
840d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'ostatic time_t parse_time(char *str)
841d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o{
842d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o	struct	tm	ts;
843d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o
844d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o	if (strcmp(str, "now") == 0) {
845d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o		return (time(0));
846d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o	}
847d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o	memset(&ts, 0, sizeof(ts));
848bc7c14e0408665addd01b978b1950963b1ed799fTheodore Ts'o#ifdef HAVE_STRPTIME
849690e693cafa83eadbf7ce80291f53a7e89e9c2ccTheodore Ts'o	strptime(str, "%Y%m%d%H%M%S", &ts);
850bc7c14e0408665addd01b978b1950963b1ed799fTheodore Ts'o#else
851690e693cafa83eadbf7ce80291f53a7e89e9c2ccTheodore Ts'o	sscanf(str, "%4d%2d%2d%2d%2d%2d", &ts.tm_year, &ts.tm_mon,
852bc7c14e0408665addd01b978b1950963b1ed799fTheodore Ts'o	       &ts.tm_mday, &ts.tm_hour, &ts.tm_min, &ts.tm_sec);
853bc7c14e0408665addd01b978b1950963b1ed799fTheodore Ts'o	ts.tm_year -= 1900;
854bc7c14e0408665addd01b978b1950963b1ed799fTheodore Ts'o	ts.tm_mon -= 1;
855bc7c14e0408665addd01b978b1950963b1ed799fTheodore Ts'o	if (ts.tm_year < 0 || ts.tm_mon < 0 || ts.tm_mon > 11 ||
856bc7c14e0408665addd01b978b1950963b1ed799fTheodore Ts'o	    ts.tm_mday < 0 || ts.tm_mday > 31 || ts.tm_hour > 23 ||
857bc7c14e0408665addd01b978b1950963b1ed799fTheodore Ts'o	    ts.tm_min > 59 || ts.tm_sec > 61)
858bc7c14e0408665addd01b978b1950963b1ed799fTheodore Ts'o		ts.tm_mday = 0;
859bc7c14e0408665addd01b978b1950963b1ed799fTheodore Ts'o#endif
860d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o	if (ts.tm_mday == 0) {
861d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o		com_err(program_name, 0,
862d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o			_("Couldn't parse date/time specifier: %s"),
863d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o			str);
864d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o		usage();
865d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o	}
866a2ff0f31c1987a480ffc4dacb7adf93f0aecf7f6Theodore Ts'o	ts.tm_isdst = -1;
867d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o	return (mktime(&ts));
868d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o}
869832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o
870c8c071a07319939dfd7ae2ff1dedec644d750debTheodore Ts'ostatic void parse_tune2fs_options(int argc, char **argv)
8713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
872519149fb458b0fa69c10fecd83fae42e838cf01dTheodore Ts'o	int c;
873ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o	char *tmp;
874ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o	struct group *gr;
875ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o	struct passwd *pw;
876e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	char optstring[100] = "c:e:fg:i:jlm:o:r:s:u:C:E:I:J:L:M:O:T:U:";
8773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
878e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef CONFIG_QUOTA
879e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	strcat(optstring, "Q:");
880e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
8812be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o	open_flag = 0;
8820ddfd9a529d2d33f9c5b59fd7409b716e50d45b2Theodore Ts'o
8830f8973fb092a40fd0a11b7ec95c09128c9fb8f0cTheodore Ts'o	printf("tune2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE);
884e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	while ((c = getopt(argc, argv, optstring)) != EOF)
885ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		switch (c) {
886ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'c':
887ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			max_mount_count = strtol(optarg, &tmp, 0);
888ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			if (*tmp || max_mount_count > 16000) {
889ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				com_err(program_name, 0,
890ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					_("bad mounts count - %s"),
891ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					optarg);
892ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				usage();
893ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			}
894ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			if (max_mount_count == 0)
895ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				max_mount_count = -1;
896ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			c_flag = 1;
897ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			open_flag = EXT2_FLAG_RW;
898ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
899ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'C':
900ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			mount_count = strtoul(optarg, &tmp, 0);
901ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			if (*tmp || mount_count > 16000) {
902ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				com_err(program_name, 0,
903ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					_("bad mounts count - %s"),
904ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					optarg);
905ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				usage();
906ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			}
907ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			C_flag = 1;
908ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			open_flag = EXT2_FLAG_RW;
909ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
910ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'e':
911ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			if (strcmp(optarg, "continue") == 0)
912ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				errors = EXT2_ERRORS_CONTINUE;
913ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			else if (strcmp(optarg, "remount-ro") == 0)
914ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				errors = EXT2_ERRORS_RO;
915ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			else if (strcmp(optarg, "panic") == 0)
916ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				errors = EXT2_ERRORS_PANIC;
917ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			else {
918ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				com_err(program_name, 0,
919ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					_("bad error behavior - %s"),
920ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					optarg);
921ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				usage();
922ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			}
923ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			e_flag = 1;
924ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			open_flag = EXT2_FLAG_RW;
925ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
926ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'E':
927ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			extended_cmd = optarg;
928ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			open_flag |= EXT2_FLAG_RW;
929ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
930ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'f': /* Force */
931ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			f_flag = 1;
932ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
933ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'g':
934ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			resgid = strtoul(optarg, &tmp, 0);
935ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			if (*tmp) {
936ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				gr = getgrnam(optarg);
937ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				if (gr == NULL)
938ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					tmp = optarg;
939818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'o				else {
940ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					resgid = gr->gr_gid;
941ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					*tmp = 0;
942f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o				}
943ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			}
944ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			if (*tmp) {
945ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				com_err(program_name, 0,
946ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					_("bad gid/group name - %s"),
947ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					optarg);
948ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				usage();
949ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			}
950ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			g_flag = 1;
951ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			open_flag = EXT2_FLAG_RW;
952ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
953ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'i':
954ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			interval = strtoul(optarg, &tmp, 0);
955ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			switch (*tmp) {
956ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			case 's':
957ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				tmp++;
958f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o				break;
959ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			case '\0':
960ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			case 'd':
961ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			case 'D': /* days */
962ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				interval *= 86400;
963ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				if (*tmp != '\0')
9641e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o					tmp++;
9651e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o				break;
9663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			case 'm':
967ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			case 'M': /* months! */
968ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				interval *= 86400 * 30;
969ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				tmp++;
9703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				break;
971ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			case 'w':
972ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			case 'W': /* weeks */
973ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				interval *= 86400 * 7;
974ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				tmp++;
975a0c3fd5e4cdc2e0b032c9ace89d960a622069c32Theodore Ts'o				break;
976ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			}
977ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			if (*tmp) {
978ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				com_err(program_name, 0,
979ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					_("bad interval - %s"), optarg);
980ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				usage();
981ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			}
982ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			i_flag = 1;
983ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			open_flag = EXT2_FLAG_RW;
984ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
985ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'j':
986ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			if (!journal_size)
987ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				journal_size = -1;
988ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			open_flag = EXT2_FLAG_RW;
989ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
990ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'J':
991ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			parse_journal_opts(optarg);
992ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			open_flag = EXT2_FLAG_RW;
993ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
994ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'l':
995ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			l_flag = 1;
996ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
997ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'L':
998ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			new_label = optarg;
999ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			L_flag = 1;
1000ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			open_flag |= EXT2_FLAG_RW |
1001ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				EXT2_FLAG_JOURNAL_DEV_OK;
1002ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
1003ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'm':
1004ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			reserved_ratio = strtod(optarg, &tmp);
10058d8224550c1f5b5c77afbf5acd95f73979276a0aTheodore Ts'o			if (*tmp || reserved_ratio > 50 ||
10068d8224550c1f5b5c77afbf5acd95f73979276a0aTheodore Ts'o			    reserved_ratio < 0) {
1007ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				com_err(program_name, 0,
1008ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					_("bad reserved block ratio - %s"),
1009ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					optarg);
1010ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				usage();
1011ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			}
1012ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			m_flag = 1;
1013ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			open_flag = EXT2_FLAG_RW;
1014ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
1015ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'M':
1016ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			new_last_mounted = optarg;
1017ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			M_flag = 1;
1018ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			open_flag = EXT2_FLAG_RW;
1019ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
1020ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'o':
1021ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			if (mntopts_cmd) {
1022e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				com_err(program_name, 0, "%s",
1023ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					_("-o may only be specified once"));
1024ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				usage();
1025ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			}
1026ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			mntopts_cmd = optarg;
1027ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			open_flag = EXT2_FLAG_RW;
1028ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
1029ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'O':
1030ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			if (features_cmd) {
1031e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				com_err(program_name, 0, "%s",
1032ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					_("-O may only be specified once"));
1033ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				usage();
1034ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			}
1035ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			features_cmd = optarg;
1036ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			open_flag = EXT2_FLAG_RW;
1037ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
1038e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef CONFIG_QUOTA
1039e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		case 'Q':
1040e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			Q_flag = 1;
1041e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			parse_quota_opts(optarg);
1042e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			open_flag = EXT2_FLAG_RW;
1043e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			break;
1044e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
1045ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'r':
1046ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			reserved_blocks = strtoul(optarg, &tmp, 0);
1047ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			if (*tmp) {
1048ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				com_err(program_name, 0,
1049ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					_("bad reserved blocks count - %s"),
1050ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					optarg);
1051ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				usage();
1052ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			}
1053ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			r_flag = 1;
1054ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			open_flag = EXT2_FLAG_RW;
1055ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
1056ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 's': /* Deprecated */
1057ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			s_flag = atoi(optarg);
1058ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			open_flag = EXT2_FLAG_RW;
1059ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
1060ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'T':
1061ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			T_flag = 1;
1062ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			last_check_time = parse_time(optarg);
1063ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			open_flag = EXT2_FLAG_RW;
1064ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
1065ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'u':
1066ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				resuid = strtoul(optarg, &tmp, 0);
1067818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'o				if (*tmp) {
1068ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					pw = getpwnam(optarg);
1069f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o					if (pw == NULL)
1070f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o						tmp = optarg;
1071a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o					else {
1072f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o						resuid = pw->pw_uid;
1073a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o						*tmp = 0;
1074a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o					}
1075f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o				}
1076818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'o				if (*tmp) {
1077ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					com_err(program_name, 0,
1078ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o						_("bad uid/user name - %s"),
1079ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o						optarg);
1080818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'o					usage();
1081f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o				}
1082f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o				u_flag = 1;
10831e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o				open_flag = EXT2_FLAG_RW;
10841e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o				break;
1085ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'U':
1086ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			new_UUID = optarg;
1087ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			U_flag = 1;
1088ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			open_flag = EXT2_FLAG_RW |
1089ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				EXT2_FLAG_JOURNAL_DEV_OK;
1090ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
1091ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		case 'I':
1092ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			new_inode_size = strtoul(optarg, &tmp, 0);
1093ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			if (*tmp) {
1094ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				com_err(program_name, 0,
1095ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					_("bad inode size - %s"),
1096ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					optarg);
1097818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'o				usage();
1098ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			}
1099ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			if (!((new_inode_size &
1100ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			       (new_inode_size - 1)) == 0)) {
1101ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				com_err(program_name, 0,
1102ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					_("Inode size must be a "
1103ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					  "power of two- %s"),
1104ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o					optarg);
1105ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				usage();
1106ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			}
1107ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			open_flag = EXT2_FLAG_RW;
1108ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			I_flag = 1;
1109ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			break;
1110ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		default:
1111ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			usage();
11123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
11133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (optind < argc - 1 || optind == argc)
1114818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'o		usage();
11151e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	if (!open_flag && !l_flag)
11161e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		usage();
11172e8ca9a26b0bd7dae546a3f9a98df67b043fe3beTheodore Ts'o	io_options = strchr(argv[optind], '?');
11182e8ca9a26b0bd7dae546a3f9a98df67b043fe3beTheodore Ts'o	if (io_options)
11192e8ca9a26b0bd7dae546a3f9a98df67b043fe3beTheodore Ts'o		*io_options++ = 0;
1120332f2c23821a17808b2566a7200b286ba9bc855aTheodore Ts'o	device_name = blkid_get_devname(NULL, argv[optind], NULL);
1121817e49e3ce0a70252113438440fc12607140d032Theodore Ts'o	if (!device_name) {
1122e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		com_err(program_name, 0, _("Unable to resolve '%s'"),
1123817e49e3ce0a70252113438440fc12607140d032Theodore Ts'o			argv[optind]);
1124817e49e3ce0a70252113438440fc12607140d032Theodore Ts'o		exit(1);
1125817e49e3ce0a70252113438440fc12607140d032Theodore Ts'o	}
1126118d7dacc535fde4e2ed8d996de3919aa0eb2e98Theodore Ts'o}
1127118d7dacc535fde4e2ed8d996de3919aa0eb2e98Theodore Ts'o
112814b596d40997c7e55ec8928bd222787f96808a2bTheodore Ts'o#ifdef CONFIG_BUILD_FINDFS
11293e69906495d5898849a6154b0311b5d4a84a27aeTheodore Ts'ovoid do_findfs(int argc, char **argv)
1130118d7dacc535fde4e2ed8d996de3919aa0eb2e98Theodore Ts'o{
1131118d7dacc535fde4e2ed8d996de3919aa0eb2e98Theodore Ts'o	char	*dev;
1132832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o
1133118d7dacc535fde4e2ed8d996de3919aa0eb2e98Theodore Ts'o	if ((argc != 2) ||
1134118d7dacc535fde4e2ed8d996de3919aa0eb2e98Theodore Ts'o	    (strncmp(argv[1], "LABEL=", 6) && strncmp(argv[1], "UUID=", 5))) {
1135118d7dacc535fde4e2ed8d996de3919aa0eb2e98Theodore Ts'o		fprintf(stderr, "Usage: findfs LABEL=<label>|UUID=<uuid>\n");
1136118d7dacc535fde4e2ed8d996de3919aa0eb2e98Theodore Ts'o		exit(2);
1137118d7dacc535fde4e2ed8d996de3919aa0eb2e98Theodore Ts'o	}
1138ed1b33e8fb310641684d68a177c940b58f2f529dTheodore Ts'o	dev = blkid_get_devname(NULL, argv[1], NULL);
1139118d7dacc535fde4e2ed8d996de3919aa0eb2e98Theodore Ts'o	if (!dev) {
1140efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		com_err("findfs", 0, _("Unable to resolve '%s'"),
1141118d7dacc535fde4e2ed8d996de3919aa0eb2e98Theodore Ts'o			argv[1]);
1142118d7dacc535fde4e2ed8d996de3919aa0eb2e98Theodore Ts'o		exit(1);
1143118d7dacc535fde4e2ed8d996de3919aa0eb2e98Theodore Ts'o	}
1144118d7dacc535fde4e2ed8d996de3919aa0eb2e98Theodore Ts'o	puts(dev);
1145118d7dacc535fde4e2ed8d996de3919aa0eb2e98Theodore Ts'o	exit(0);
1146118d7dacc535fde4e2ed8d996de3919aa0eb2e98Theodore Ts'o}
114714b596d40997c7e55ec8928bd222787f96808a2bTheodore Ts'o#endif
1148832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o
1149e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic int parse_extended_opts(ext2_filsys fs, const char *opts)
11506cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o{
11516cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o	char	*buf, *token, *next, *p, *arg;
115210ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o	int	len, hash_alg;
11536cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o	int	r_usage = 0;
11546cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o
11556cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o	len = strlen(opts);
11566cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o	buf = malloc(len+1);
11576cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o	if (!buf) {
1158e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		fprintf(stderr, "%s",
11596cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o			_("Couldn't allocate memory to parse options!\n"));
1160e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return 1;
11616cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o	}
11626cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o	strcpy(buf, opts);
11636cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o	for (token = buf; token && *token; token = next) {
11646cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o		p = strchr(token, ',');
11656cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o		next = 0;
11666cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o		if (p) {
11676cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o			*p = 0;
11686cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o			next = p+1;
11696cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o		}
11706cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o		arg = strchr(token, '=');
11716cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o		if (arg) {
11726cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o			*arg = 0;
11736cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o			arg++;
11746cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o		}
1175e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (strcmp(token, "clear-mmp") == 0 ||
1176e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		    strcmp(token, "clear_mmp") == 0) {
1177e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			clear_mmp = 1;
1178e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		} else if (strcmp(token, "mmp_update_interval") == 0) {
1179e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			unsigned long intv;
1180e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			if (!arg) {
1181e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				r_usage++;
1182e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				continue;
1183e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			}
1184e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			intv = strtoul(arg, &p, 0);
1185e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			if (*p) {
1186e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				fprintf(stderr,
1187e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					_("Invalid mmp_update_interval: %s\n"),
1188e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					arg);
1189e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				r_usage++;
1190e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				continue;
1191e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			}
1192e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			if (intv == 0) {
1193e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				intv = EXT4_MMP_UPDATE_INTERVAL;
1194e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			} else if (intv > EXT4_MMP_MAX_UPDATE_INTERVAL) {
1195e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				fprintf(stderr,
1196e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					_("mmp_update_interval too big: %lu\n"),
1197e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					intv);
1198e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				r_usage++;
1199e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				continue;
1200e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			}
1201e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			printf(P_("Setting multiple mount protection update "
1202e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				  "interval to %lu second\n",
1203e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				  "Setting multiple mount protection update "
1204e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				  "interval to %lu seconds\n", intv),
1205e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			       intv);
1206e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			fs->super->s_mmp_update_interval = intv;
1207e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_mark_super_dirty(fs);
1208e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		} else if (!strcmp(token, "test_fs")) {
12096cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o			fs->super->s_flags |= EXT2_FLAGS_TEST_FILESYS;
12106cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o			printf("Setting test filesystem flag\n");
12116cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o			ext2fs_mark_super_dirty(fs);
12126cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o		} else if (!strcmp(token, "^test_fs")) {
12136cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o			fs->super->s_flags &= ~EXT2_FLAGS_TEST_FILESYS;
12146cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o			printf("Clearing test filesystem flag\n");
12156cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o			ext2fs_mark_super_dirty(fs);
12160c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o		} else if (strcmp(token, "stride") == 0) {
12170c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o			if (!arg) {
12180c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o				r_usage++;
12190c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o				continue;
12200c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o			}
12210c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o			stride = strtoul(arg, &p, 0);
1222e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			if (*p) {
12230c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o				fprintf(stderr,
1224e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					_("Invalid RAID stride: %s\n"),
12250c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o					arg);
12260c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o				r_usage++;
12270c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o				continue;
12280c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o			}
12290c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o			stride_set = 1;
12300c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o		} else if (strcmp(token, "stripe-width") == 0 ||
12310c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o			   strcmp(token, "stripe_width") == 0) {
12320c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o			if (!arg) {
12330c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o				r_usage++;
12340c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o				continue;
12350c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o			}
12360c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o			stripe_width = strtoul(arg, &p, 0);
1237e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			if (*p) {
12380c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o				fprintf(stderr,
12390c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o					_("Invalid RAID stripe-width: %s\n"),
12400c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o					arg);
12410c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o				r_usage++;
12420c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o				continue;
12430c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o			}
12440c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o			stripe_width_set = 1;
124510ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o		} else if (strcmp(token, "hash_alg") == 0 ||
124610ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o			   strcmp(token, "hash-alg") == 0) {
124710ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o			if (!arg) {
124810ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o				r_usage++;
124910ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o				continue;
125010ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o			}
125110ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o			hash_alg = e2p_string2hash(arg);
125210ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o			if (hash_alg < 0) {
1253ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				fprintf(stderr,
125410ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o					_("Invalid hash algorithm: %s\n"),
125510ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o					arg);
125610ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o				r_usage++;
125710ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o				continue;
125810ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o			}
125910ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o			fs->super->s_def_hash_version = hash_alg;
126010ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o			printf(_("Setting default hash algorithm "
1261ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				 "to %s (%d)\n"),
126210ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o			       arg, hash_alg);
126310ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o			ext2fs_mark_super_dirty(fs);
1264e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		} else if (!strcmp(token, "mount_opts")) {
12659345f02671fd39cad69338080b62e12e8b86671dTheodore Ts'o			if (!arg) {
12669345f02671fd39cad69338080b62e12e8b86671dTheodore Ts'o				r_usage++;
12679345f02671fd39cad69338080b62e12e8b86671dTheodore Ts'o				continue;
12689345f02671fd39cad69338080b62e12e8b86671dTheodore Ts'o			}
12699345f02671fd39cad69338080b62e12e8b86671dTheodore Ts'o			if (strlen(arg) >= sizeof(fs->super->s_mount_opts)) {
12709345f02671fd39cad69338080b62e12e8b86671dTheodore Ts'o				fprintf(stderr,
12719345f02671fd39cad69338080b62e12e8b86671dTheodore Ts'o					"Extended mount options too long\n");
12729345f02671fd39cad69338080b62e12e8b86671dTheodore Ts'o				continue;
12739345f02671fd39cad69338080b62e12e8b86671dTheodore Ts'o			}
1274e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext_mount_opts = strdup(arg);
1275efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		} else
12766cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o			r_usage++;
12776cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o	}
12786cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o	if (r_usage) {
1279e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		fprintf(stderr, "%s", _("\nBad options specified.\n\n"
12806cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o			"Extended options are separated by commas, "
12816cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o			"and may take an argument which\n"
12826cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o			"\tis set off by an equals ('=') sign.\n\n"
12836cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o			"Valid extended options are:\n"
1284e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			"\tclear_mmp\n"
1285e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			"\thash_alg=<hash algorithm>\n"
1286e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			"\tmount_opts=<extended default mount options>\n"
12870c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o			"\tstride=<RAID per-disk chunk size in blocks>\n"
128810ff68d42d06953c35459a0d949862e6aafa19f8Theodore Ts'o			"\tstripe_width=<RAID stride*data disks in blocks>\n"
12896cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o			"\ttest_fs\n"
12906cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o			"\t^test_fs\n"));
12916cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o		free(buf);
1292e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return 1;
12936cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o	}
12946cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o	free(buf);
1295e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
1296e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return 0;
1297efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o}
12986cb27404f51f97e2665fa0e0c4c0f7bc47e698ecTheodore Ts'o
129931f1815fa9a1b7ca41afdf6d364a6474eba8b6d1Theodore Ts'o/*
1300a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V * Fill in the block bitmap bmap with the information regarding the
1301a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V * blocks to be moved
130231f1815fa9a1b7ca41afdf6d364a6474eba8b6d1Theodore Ts'o */
130331f1815fa9a1b7ca41afdf6d364a6474eba8b6d1Theodore Ts'ostatic int get_move_bitmaps(ext2_filsys fs, int new_ino_blks_per_grp,
1304a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V			    ext2fs_block_bitmap bmap)
130564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V{
130664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	dgrp_t i;
1307154a5d7537c35959aa646ef8f18daed8c9f1a2beAneesh Kumar K.V	int retval;
1308154a5d7537c35959aa646ef8f18daed8c9f1a2beAneesh Kumar K.V	ext2_badblocks_list bb_list = 0;
1309e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t j, needed_blocks = 0;
1310e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t start_blk, end_blk;
131164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1312154a5d7537c35959aa646ef8f18daed8c9f1a2beAneesh Kumar K.V	retval = ext2fs_read_bb_inode(fs, &bb_list);
1313154a5d7537c35959aa646ef8f18daed8c9f1a2beAneesh Kumar K.V	if (retval)
1314154a5d7537c35959aa646ef8f18daed8c9f1a2beAneesh Kumar K.V		return retval;
1315154a5d7537c35959aa646ef8f18daed8c9f1a2beAneesh Kumar K.V
131664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	for (i = 0; i < fs->group_desc_count; i++) {
1317e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		start_blk = ext2fs_inode_table_loc(fs, i) +
131864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V					fs->inode_blocks_per_group;
131964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1320e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		end_blk = ext2fs_inode_table_loc(fs, i) +
132164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V					new_ino_blks_per_grp;
132264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
132364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		for (j = start_blk; j < end_blk; j++) {
1324e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			if (ext2fs_test_block_bitmap2(fs->block_map, j)) {
1325154a5d7537c35959aa646ef8f18daed8c9f1a2beAneesh Kumar K.V				/*
1326154a5d7537c35959aa646ef8f18daed8c9f1a2beAneesh Kumar K.V				 * IF the block is a bad block we fail
132764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V				 */
1328154a5d7537c35959aa646ef8f18daed8c9f1a2beAneesh Kumar K.V				if (ext2fs_badblocks_list_test(bb_list, j)) {
1329154a5d7537c35959aa646ef8f18daed8c9f1a2beAneesh Kumar K.V					ext2fs_badblocks_list_free(bb_list);
1330154a5d7537c35959aa646ef8f18daed8c9f1a2beAneesh Kumar K.V					return ENOSPC;
1331154a5d7537c35959aa646ef8f18daed8c9f1a2beAneesh Kumar K.V				}
1332154a5d7537c35959aa646ef8f18daed8c9f1a2beAneesh Kumar K.V
1333e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				ext2fs_mark_block_bitmap2(bmap, j);
133464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			} else {
133564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V				/*
133664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V				 * We are going to use this block for
133764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V				 * inode table. So mark them used.
133864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V				 */
1339e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				ext2fs_mark_block_bitmap2(fs->block_map, j);
134064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			}
134164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		}
1342a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V		needed_blocks += end_blk - start_blk;
134364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	}
134464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1345154a5d7537c35959aa646ef8f18daed8c9f1a2beAneesh Kumar K.V	ext2fs_badblocks_list_free(bb_list);
1346e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (needed_blocks > ext2fs_free_blocks_count(fs->super))
134764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		return ENOSPC;
134864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
134964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	return 0;
135064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V}
135164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1352e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic int ext2fs_is_meta_block(ext2_filsys fs, blk64_t blk)
135391fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V{
135491fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V	dgrp_t group;
1355e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	group = ext2fs_group_of_blk2(fs, blk);
1356e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (ext2fs_block_bitmap_loc(fs, group) == blk)
135791fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V		return 1;
1358e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (ext2fs_inode_bitmap_loc(fs, group) == blk)
135991fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V		return 1;
136091fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V	return 0;
136191fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V}
136291fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V
1363e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic int ext2fs_is_block_in_group(ext2_filsys fs, dgrp_t group, blk64_t blk)
136491fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V{
1365e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t start_blk, end_blk;
136691fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V	start_blk = fs->super->s_first_data_block +
136791fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V			EXT2_BLOCKS_PER_GROUP(fs->super) * group;
136891fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V	/*
136991fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V	 * We cannot get new block beyond end_blk for for the last block group
137091fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V	 * so we can check with EXT2_BLOCKS_PER_GROUP even for last block group
137191fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V	 */
137291fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V	end_blk   = start_blk + EXT2_BLOCKS_PER_GROUP(fs->super);
137391fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V	if (blk >= start_blk && blk <= end_blk)
137491fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V		return 1;
137591fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V	return 0;
137691fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V}
137791fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V
1378a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.Vstatic int move_block(ext2_filsys fs, ext2fs_block_bitmap bmap)
137964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V{
138091fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V
138164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	char *buf;
1382e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	dgrp_t group = 0;
138364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	errcode_t retval;
138491fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V	int meta_data = 0;
1385e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t blk, new_blk, goal;
138664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	struct blk_move *bmv;
138764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
138864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	retval = ext2fs_get_mem(fs->blocksize, &buf);
138964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	if (retval)
139064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		return retval;
139164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
139227c6de45a4187a348ec0960472d4a113ee6ea425Theodore Ts'o	for (new_blk = blk = fs->super->s_first_data_block;
1393e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	     blk < ext2fs_blocks_count(fs->super); blk++) {
1394e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (!ext2fs_test_block_bitmap2(bmap, blk))
139564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			continue;
139664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
139791fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V		if (ext2fs_is_meta_block(fs, blk)) {
139891fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V			/*
139991fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V			 * If the block is mapping a fs meta data block
140091fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V			 * like group desc/block bitmap/inode bitmap. We
140191fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V			 * should find a block in the same group and fix
140291fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V			 * the respective fs metadata pointers. Otherwise
140391fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V			 * fail
140491fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V			 */
1405e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			group = ext2fs_group_of_blk2(fs, blk);
1406e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goal = ext2fs_group_first_block2(fs, group);
140791fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V			meta_data = 1;
140891fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V
140991fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V		} else {
141091fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V			goal = new_blk;
141191fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V		}
1412e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		retval = ext2fs_new_block2(fs, goal, NULL, &new_blk);
141364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		if (retval)
141464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			goto err_out;
141564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
141691fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V		/* new fs meta data block should be in the same group */
141791fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V		if (meta_data && !ext2fs_is_block_in_group(fs, group, new_blk)) {
141891fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V			retval = ENOSPC;
141991fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V			goto err_out;
142091fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V		}
142191fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V
142264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		/* Mark this block as allocated */
1423e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_mark_block_bitmap2(fs->block_map, new_blk);
142464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
142564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		/* Add it to block move list */
142664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		retval = ext2fs_get_mem(sizeof(struct blk_move), &bmv);
142764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		if (retval)
142864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			goto err_out;
142964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
143064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		bmv->old_loc = blk;
143164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		bmv->new_loc = new_blk;
143264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
143364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		list_add(&(bmv->list), &blk_move_list);
143464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1435e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		retval = io_channel_read_blk64(fs->io, blk, 1, buf);
143664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		if (retval)
143764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			goto err_out;
143864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1439e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		retval = io_channel_write_blk64(fs->io, new_blk, 1, buf);
144064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		if (retval)
144164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			goto err_out;
144264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	}
144364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
144464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.Verr_out:
144564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	ext2fs_free_mem(&buf);
144664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	return retval;
144764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V}
144864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1449e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic blk64_t translate_block(blk64_t blk)
145064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V{
145164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	struct list_head *entry;
145264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	struct blk_move *bmv;
145364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
145464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	list_for_each(entry, &blk_move_list) {
145564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		bmv = list_entry(entry, struct blk_move, list);
145664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		if (bmv->old_loc == blk)
145764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			return bmv->new_loc;
145864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	}
145964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
146064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	return 0;
146164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V}
146264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1463721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'ostatic int process_block(ext2_filsys fs EXT2FS_ATTR((unused)),
1464e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			 blk64_t *block_nr,
1465721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o			 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
1466e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			 blk64_t ref_block EXT2FS_ATTR((unused)),
146764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			 int ref_offset EXT2FS_ATTR((unused)),
146827c6de45a4187a348ec0960472d4a113ee6ea425Theodore Ts'o			 void *priv_data)
146964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V{
147064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	int ret = 0;
1471e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t new_blk;
147227c6de45a4187a348ec0960472d4a113ee6ea425Theodore Ts'o	ext2fs_block_bitmap bmap = (ext2fs_block_bitmap) priv_data;
147364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1474e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!ext2fs_test_block_bitmap2(bmap, *block_nr))
147527c6de45a4187a348ec0960472d4a113ee6ea425Theodore Ts'o		return 0;
1476ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o	new_blk = translate_block(*block_nr);
147764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	if (new_blk) {
147864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		*block_nr = new_blk;
147964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		/*
148064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		 * This will force the ext2fs_write_inode in the iterator
148164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		 */
148264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		ret |= BLOCK_CHANGED;
148364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	}
148464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
148564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	return ret;
148664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V}
148764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
148827c6de45a4187a348ec0960472d4a113ee6ea425Theodore Ts'ostatic int inode_scan_and_fix(ext2_filsys fs, ext2fs_block_bitmap bmap)
148964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V{
149064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	errcode_t retval = 0;
149164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	ext2_ino_t ino;
1492e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t blk;
149364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	char *block_buf = 0;
149464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	struct ext2_inode inode;
149564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	ext2_inode_scan	scan = NULL;
149664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
149764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	retval = ext2fs_get_mem(fs->blocksize * 3, &block_buf);
149864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	if (retval)
149964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		return retval;
150064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
150164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	retval = ext2fs_open_inode_scan(fs, 0, &scan);
150264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	if (retval)
150364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		goto err_out;
150464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
150564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	while (1) {
150664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		retval = ext2fs_get_next_inode(scan, &ino, &inode);
150764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		if (retval)
150864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			goto err_out;
150964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
151064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		if (!ino)
151164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			break;
151264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
151364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		if (inode.i_links_count == 0)
151464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			continue; /* inode not in use */
151564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
151664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		/* FIXME!!
151764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		 * If we end up modifying the journal inode
151864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		 * the sb->s_jnl_blocks will differ. But a
151964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		 * subsequent e2fsck fixes that.
152064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		 * Do we need to fix this ??
152164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		 */
152264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1523e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (ext2fs_file_acl_block(fs, &inode) &&
1524e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		    ext2fs_test_block_bitmap2(bmap,
1525e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					ext2fs_file_acl_block(fs, &inode))) {
1526e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			blk = translate_block(ext2fs_file_acl_block(fs,
1527e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall								    &inode));
152864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			if (!blk)
152964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V				continue;
153064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1531e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_file_acl_block_set(fs, &inode, blk);
153264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
153364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			/*
153464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			 * Write the inode to disk so that inode table
153564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			 * resizing can work
153664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			 */
153764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			retval = ext2fs_write_inode(fs, ino, &inode);
153864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			if (retval)
153964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V				goto err_out;
154064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		}
154164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1542e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (!ext2fs_inode_has_valid_blocks2(fs, &inode))
154364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			continue;
154464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1545e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		retval = ext2fs_block_iterate3(fs, ino, 0, block_buf,
154627c6de45a4187a348ec0960472d4a113ee6ea425Theodore Ts'o					       process_block, bmap);
154764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		if (retval)
154864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			goto err_out;
154964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
155064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	}
155164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
155264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.Verr_out:
155364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	ext2fs_free_mem(&block_buf);
155464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
155564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	return retval;
155631f1815fa9a1b7ca41afdf6d364a6474eba8b6d1Theodore Ts'o}
155731f1815fa9a1b7ca41afdf6d364a6474eba8b6d1Theodore Ts'o
155891fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V/*
155991fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V * We need to scan for inode and block bitmaps that may need to be
156091fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V * moved.  This can take place if the filesystem was formatted for
156191fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V * RAID arrays using the mke2fs's extended option "stride".
156291fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V */
156391fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.Vstatic int group_desc_scan_and_fix(ext2_filsys fs, ext2fs_block_bitmap bmap)
156491fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V{
156591fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V	dgrp_t i;
1566e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t blk, new_blk;
156791fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V
156891fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V	for (i = 0; i < fs->group_desc_count; i++) {
1569e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		blk = ext2fs_block_bitmap_loc(fs, i);
1570e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (ext2fs_test_block_bitmap2(bmap, blk)) {
157191fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V			new_blk = translate_block(blk);
157291fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V			if (!new_blk)
157391fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V				continue;
1574e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_block_bitmap_loc_set(fs, i, new_blk);
157591fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V		}
157691fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V
1577e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		blk = ext2fs_inode_bitmap_loc(fs, i);
1578e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (ext2fs_test_block_bitmap2(bmap, blk)) {
157991fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V			new_blk = translate_block(blk);
158091fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V			if (!new_blk)
158191fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V				continue;
1582e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_inode_bitmap_loc_set(fs, i, new_blk);
158391fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V		}
158491fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V	}
158591fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V	return 0;
158691fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V}
158791fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V
1588721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'ostatic int expand_inode_table(ext2_filsys fs, unsigned long new_ino_size)
158964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V{
159064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	dgrp_t i;
1591e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t blk;
159264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	errcode_t retval;
1593721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o	int new_ino_blks_per_grp;
1594721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o	unsigned int j;
159564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	char *old_itable = NULL, *new_itable = NULL;
159664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	char *tmp_old_itable = NULL, *tmp_new_itable = NULL;
1597721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o	unsigned long old_ino_size;
159864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	int old_itable_size, new_itable_size;
159964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
160064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	old_itable_size = fs->inode_blocks_per_group * fs->blocksize;
1601721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o	old_ino_size = EXT2_INODE_SIZE(fs->super);
160264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
160364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	new_ino_blks_per_grp = ext2fs_div_ceil(
160464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V					EXT2_INODES_PER_GROUP(fs->super) *
1605721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o					new_ino_size,
160664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V					fs->blocksize);
160764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
160864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	new_itable_size = new_ino_blks_per_grp * fs->blocksize;
160964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
161064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	retval = ext2fs_get_mem(old_itable_size, &old_itable);
161164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	if (retval)
161264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		return retval;
161364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
161464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	retval = ext2fs_get_mem(new_itable_size, &new_itable);
161564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	if (retval)
161664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		goto err_out;
161764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
161864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	tmp_old_itable = old_itable;
161964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	tmp_new_itable = new_itable;
162064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
162164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	for (i = 0; i < fs->group_desc_count; i++) {
1622e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		blk = ext2fs_inode_table_loc(fs, i);
1623e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		retval = io_channel_read_blk64(fs->io, blk,
162464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V				fs->inode_blocks_per_group, old_itable);
162564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		if (retval)
162664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			goto err_out;
162764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
162864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		for (j = 0; j < EXT2_INODES_PER_GROUP(fs->super); j++) {
1629721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o			memcpy(new_itable, old_itable, old_ino_size);
163064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1631721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o			memset(new_itable+old_ino_size, 0,
1632721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o					new_ino_size - old_ino_size);
163364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1634721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o			new_itable += new_ino_size;
1635721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o			old_itable += old_ino_size;
163664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		}
163764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
163864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		/* reset the pointer */
163964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		old_itable = tmp_old_itable;
164064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		new_itable = tmp_new_itable;
164164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1642e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		retval = io_channel_write_blk64(fs->io, blk,
164364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V					new_ino_blks_per_grp, new_itable);
164464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		if (retval)
164564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			goto err_out;
164664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	}
164764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
164864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	/* Update the meta data */
164964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	fs->inode_blocks_per_group = new_ino_blks_per_grp;
1650721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o	fs->super->s_inode_size = new_ino_size;
165164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
165264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.Verr_out:
165364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	if (old_itable)
165464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		ext2fs_free_mem(&old_itable);
165564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
165664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	if (new_itable)
165764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		ext2fs_free_mem(&new_itable);
165864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
165964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	return retval;
166064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V}
166164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
166264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.Vstatic errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs)
166364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V{
1664e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t		blk;
166564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	ext2_ino_t	ino;
166664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	unsigned int	group = 0;
166764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	unsigned int	count = 0;
166864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	int		total_free = 0;
166964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	int		group_free = 0;
167064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
167164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	/*
167264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	 * First calculate the block statistics
167364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	 */
167464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	for (blk = fs->super->s_first_data_block;
1675e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	     blk < ext2fs_blocks_count(fs->super); blk++) {
1676e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (!ext2fs_fast_test_block_bitmap2(fs->block_map, blk)) {
167764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			group_free++;
167864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			total_free++;
167964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		}
168064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		count++;
168164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		if ((count == fs->super->s_blocks_per_group) ||
1682e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		    (blk == ext2fs_blocks_count(fs->super)-1)) {
1683e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_bg_free_blocks_count_set(fs, group++,
1684e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall							group_free);
168564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			count = 0;
168664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			group_free = 0;
168764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		}
168864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	}
1689e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	total_free = EXT2FS_C2B(fs, total_free);
1690e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	ext2fs_free_blocks_count_set(fs->super, total_free);
169164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
169264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	/*
169364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	 * Next, calculate the inode statistics
169464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	 */
169564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	group_free = 0;
169664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	total_free = 0;
169764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	count = 0;
169864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	group = 0;
169964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
170064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	/* Protect loop from wrap-around if s_inodes_count maxed */
170164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	for (ino = 1; ino <= fs->super->s_inodes_count && ino > 0; ino++) {
1702e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (!ext2fs_fast_test_inode_bitmap2(fs->inode_map, ino)) {
170364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			group_free++;
170464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			total_free++;
170564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		}
170664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		count++;
170764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		if ((count == fs->super->s_inodes_per_group) ||
170864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		    (ino == fs->super->s_inodes_count)) {
1709e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_bg_free_inodes_count_set(fs, group++,
1710e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall							group_free);
171164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			count = 0;
171264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			group_free = 0;
171364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		}
171464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	}
171564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	fs->super->s_free_inodes_count = total_free;
171664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	ext2fs_mark_super_dirty(fs);
171764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	return 0;
171864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V}
171964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
172064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V#define list_for_each_safe(pos, pnext, head) \
172164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	for (pos = (head)->next, pnext = pos->next; pos != (head); \
172264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	     pos = pnext, pnext = pos->next)
172364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1724721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'ostatic void free_blk_move_list(void)
172564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V{
172664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	struct list_head *entry, *tmp;
172764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	struct blk_move *bmv;
172864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
172964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	list_for_each_safe(entry, tmp, &blk_move_list) {
173064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		bmv = list_entry(entry, struct blk_move, list);
173164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		list_del(entry);
173264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		ext2fs_free_mem(&bmv);
173364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	}
173431f1815fa9a1b7ca41afdf6d364a6474eba8b6d1Theodore Ts'o	return;
173564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V}
1736721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o
1737721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'ostatic int resize_inode(ext2_filsys fs, unsigned long new_size)
173864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V{
173964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	errcode_t retval;
174064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	int new_ino_blks_per_grp;
1741a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V	ext2fs_block_bitmap bmap;
174264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1743e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	retval = ext2fs_read_inode_bitmap(fs);
1744e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (retval) {
1745e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		fputs(_("Failed to read inode bitmap\n"), stderr);
1746e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return retval;
1747e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
1748e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	retval = ext2fs_read_block_bitmap(fs);
1749e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (retval) {
1750e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		fputs(_("Failed to read block bitmap\n"), stderr);
1751e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return retval;
1752e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
175364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	INIT_LIST_HEAD(&blk_move_list);
175464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
175564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
175664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	new_ino_blks_per_grp = ext2fs_div_ceil(
175764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V					EXT2_INODES_PER_GROUP(fs->super)*
1758721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o					new_size,
175964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V					fs->blocksize);
176064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
176164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	/* We may change the file system.
176264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	 * Mark the file system as invalid so that
176364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	 * the user is prompted to run fsck.
176464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	 */
176564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	fs->super->s_state &= ~EXT2_VALID_FS;
176664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
176764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	retval = ext2fs_allocate_block_bitmap(fs, _("blocks to be moved"),
176864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V						&bmap);
1769a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V	if (retval) {
1770a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V		fputs(_("Failed to allocate block bitmap when "
1771a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V				"increasing inode size\n"), stderr);
177231f1815fa9a1b7ca41afdf6d364a6474eba8b6d1Theodore Ts'o		return retval;
1773a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V	}
1774a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V	retval = get_move_bitmaps(fs, new_ino_blks_per_grp, bmap);
1775a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V	if (retval) {
1776a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V		fputs(_("Not enough space to increase inode size \n"), stderr);
177764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		goto err_out;
1778a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V	}
1779a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V	retval = move_block(fs, bmap);
1780a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V	if (retval) {
1781a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V		fputs(_("Failed to relocate blocks during inode resize \n"),
1782a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V		      stderr);
178364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		goto err_out;
1784a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V	}
178527c6de45a4187a348ec0960472d4a113ee6ea425Theodore Ts'o	retval = inode_scan_and_fix(fs, bmap);
178664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	if (retval)
1787a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V		goto err_out_undo;
178831f1815fa9a1b7ca41afdf6d364a6474eba8b6d1Theodore Ts'o
178991fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V	retval = group_desc_scan_and_fix(fs, bmap);
179091fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V	if (retval)
179191fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V		goto err_out_undo;
179291fac97938f0ad8c9f0e2c75feec689ca12105e3Aneesh Kumar K.V
1793721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o	retval = expand_inode_table(fs, new_size);
179464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	if (retval)
1795a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V		goto err_out_undo;
179664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
179764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	ext2fs_calculate_summary_stats(fs);
179864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
179964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	fs->super->s_state |= EXT2_VALID_FS;
180064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	/* mark super block and block bitmap as dirty */
180164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	ext2fs_mark_super_dirty(fs);
180264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	ext2fs_mark_bb_dirty(fs);
180364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
180464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.Verr_out:
180564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	free_blk_move_list();
180664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	ext2fs_free_block_bitmap(bmap);
180764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
180864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	return retval;
1809a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V
1810a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.Verr_out_undo:
1811a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V	free_blk_move_list();
1812a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V	ext2fs_free_block_bitmap(bmap);
1813a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V	fputs(_("Error in resizing the inode size.\n"
1814a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V			"Run e2undo to undo the "
1815a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V			"file system changes. \n"), stderr);
1816a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V
1817a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V	return retval;
181864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V}
181964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
182064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.Vstatic int tune2fs_setup_tdb(const char *name, io_manager *io_ptr)
182164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V{
182264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	errcode_t retval = 0;
1823721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o	const char *tdb_dir;
1824f203bbdbec396e3279bf249ae9be96e6b00bf6f2Theodore Ts'o	char *tdb_file;
1825721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o	char *dev_name, *tmp_name;
182664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
182764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V#if 0 /* FIXME!! */
182864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	/*
182964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	 * Configuration via a conf file would be
183064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	 * nice
183164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	 */
183264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	profile_get_string(profile, "scratch_files",
183364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V					"directory", 0, 0,
183464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V					&tdb_dir);
183564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V#endif
183664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	tmp_name = strdup(name);
1837f203bbdbec396e3279bf249ae9be96e6b00bf6f2Theodore Ts'o	if (!tmp_name) {
1838f203bbdbec396e3279bf249ae9be96e6b00bf6f2Theodore Ts'o	alloc_fn_fail:
1839e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		com_err(program_name, ENOMEM, "%s",
1840f203bbdbec396e3279bf249ae9be96e6b00bf6f2Theodore Ts'o			_("Couldn't allocate memory for tdb filename\n"));
1841f203bbdbec396e3279bf249ae9be96e6b00bf6f2Theodore Ts'o		return ENOMEM;
1842f203bbdbec396e3279bf249ae9be96e6b00bf6f2Theodore Ts'o	}
1843721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o	dev_name = basename(tmp_name);
184464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
184564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	tdb_dir = getenv("E2FSPROGS_UNDO_DIR");
184664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	if (!tdb_dir)
1847ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		tdb_dir = "/var/lib/e2fsprogs";
184864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
184964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	if (!strcmp(tdb_dir, "none") || (tdb_dir[0] == 0) ||
185064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	    access(tdb_dir, W_OK))
185164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		return 0;
185264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1853f203bbdbec396e3279bf249ae9be96e6b00bf6f2Theodore Ts'o	tdb_file = malloc(strlen(tdb_dir) + 9 + strlen(dev_name) + 7 + 1);
1854f203bbdbec396e3279bf249ae9be96e6b00bf6f2Theodore Ts'o	if (!tdb_file)
1855f203bbdbec396e3279bf249ae9be96e6b00bf6f2Theodore Ts'o		goto alloc_fn_fail;
1856721b367abf1fb65d4f048b34fdf91571a0ccfdd3Theodore Ts'o	sprintf(tdb_file, "%s/tune2fs-%s.e2undo", tdb_dir, dev_name);
185764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
185864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	if (!access(tdb_file, F_OK)) {
185964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		if (unlink(tdb_file) < 0) {
186064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			retval = errno;
186164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			com_err(program_name, retval,
186264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V				_("while trying to delete %s"),
186364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V				tdb_file);
1864f203bbdbec396e3279bf249ae9be96e6b00bf6f2Theodore Ts'o			free(tdb_file);
186564d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			return retval;
186664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		}
186764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	}
186864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
186964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	set_undo_io_backing_manager(*io_ptr);
187064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	*io_ptr = undo_io_manager;
187164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	set_undo_io_backup_file(tdb_file);
18725bf81baea01a19ce48daee5db07f08c6a9655ab5Theodore Ts'o	printf(_("To undo the tune2fs operation please run "
1873577b5c436f1531d4d14bcba1bc10e230dafc9fd1Benno Schulenberg		 "the command\n    e2undo %s %s\n\n"),
187464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		 tdb_file, name);
1875f203bbdbec396e3279bf249ae9be96e6b00bf6f2Theodore Ts'o	free(tdb_file);
187664d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	free(tmp_name);
187764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	return retval;
187864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V}
1879832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o
1880d25948b9b4a9e361ef071dc8175df0407f60b7e0JP Abgrall#ifndef BUILD_AS_LIB
1881ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'oint main(int argc, char **argv)
1882d25948b9b4a9e361ef071dc8175df0407f60b7e0JP Abgrall#else
1883d25948b9b4a9e361ef071dc8175df0407f60b7e0JP Abgrallint tune2fs_main(int argc, char **argv)
1884d25948b9b4a9e361ef071dc8175df0407f60b7e0JP Abgrall#endif  /* BUILD_AS_LIB */
1885832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o{
1886832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o	errcode_t retval;
1887832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o	ext2_filsys fs;
1888832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o	struct ext2_super_block *sb;
1889d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o	io_manager io_ptr, io_ptr_orig = NULL;
1890e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	int rc = 0;
1891832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o
1892832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o#ifdef ENABLE_NLS
1893832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o	setlocale(LC_MESSAGES, "");
189414308a5398984842e808faa3ff2dd6a1c52d90bdTheodore Ts'o	setlocale(LC_CTYPE, "");
1895832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o	bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
1896832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o	textdomain(NLS_CAT_NAME);
1897e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	set_com_err_gettext(gettext);
1898832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o#endif
1899832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o	if (argc && *argv)
1900832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o		program_name = *argv;
1901a6d8302b4873527798a77c1ba3106a04b71dfeacTheodore Ts'o	add_error_table(&et_ext2_error_table);
1902832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o
190314b596d40997c7e55ec8928bd222787f96808a2bTheodore Ts'o#ifdef CONFIG_BUILD_FINDFS
1904118d7dacc535fde4e2ed8d996de3919aa0eb2e98Theodore Ts'o	if (strcmp(get_progname(argv[0]), "findfs") == 0)
1905118d7dacc535fde4e2ed8d996de3919aa0eb2e98Theodore Ts'o		do_findfs(argc, argv);
190614b596d40997c7e55ec8928bd222787f96808a2bTheodore Ts'o#endif
1907832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o	if (strcmp(get_progname(argv[0]), "e2label") == 0)
1908832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o		parse_e2label_options(argc, argv);
1909832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o	else
1910832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o		parse_tune2fs_options(argc, argv);
1911efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
19122a29f1354f793557fa1829c9e85e74586e2907dbTheodore Ts'o#ifdef CONFIG_TESTIO_DEBUG
1913f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o	if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_DEBUG")) {
1914f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o		io_ptr = test_io_manager;
1915f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o		test_io_backing_manager = unix_io_manager;
1916f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o	} else
19172a29f1354f793557fa1829c9e85e74586e2907dbTheodore Ts'o#endif
1918f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o		io_ptr = unix_io_manager;
191964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V
1920d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'oretry_open:
1921e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if ((open_flag & EXT2_FLAG_RW) == 0 || f_flag)
1922e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		open_flag |= EXT2_FLAG_SKIP_MMP;
1923e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
1924e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	open_flag |= EXT2_FLAG_64BITS;
1925e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
1926e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	/* keep the filesystem struct around to dump MMP data */
1927e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	open_flag |= EXT2_FLAG_NOFREE_ON_ERROR;
1928e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
1929efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o	retval = ext2fs_open2(device_name, io_options, open_flag,
19302e8ca9a26b0bd7dae546a3f9a98df67b043fe3beTheodore Ts'o			      0, 0, io_ptr, &fs);
1931ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o	if (retval) {
1932e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		com_err(program_name, retval,
1933e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			_("while trying to open %s"),
1934ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			device_name);
1935e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (retval == EXT2_ET_MMP_FSCK_ON ||
1936e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		    retval == EXT2_ET_MMP_UNKNOWN_SEQ)
1937e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			dump_mmp_msg(fs->mmp_buf,
1938e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				     _("If you are sure the filesystem "
1939e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				       "is not in use on any node, run:\n"
1940e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				       "'tune2fs -f -E clear_mmp {device}'\n"));
1941e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		else if (retval == EXT2_ET_MMP_FAILED)
1942e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			dump_mmp_msg(fs->mmp_buf, NULL);
1943e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		else if (retval == EXT2_ET_MMP_MAGIC_INVALID)
1944e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			fprintf(stderr,
1945e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				_("MMP block magic is bad. Try to fix it by "
1946e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				  "running:\n'e2fsck -f %s'\n"), device_name);
1947e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		else if (retval != EXT2_ET_MMP_FAILED)
1948e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			fprintf(stderr, "%s",
1949e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			     _("Couldn't find valid filesystem superblock.\n"));
1950e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
1951e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_free(fs);
19523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		exit(1);
19533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1954e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	fs->default_bitmap_type = EXT2FS_BMAP64_RBTREE;
1955d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o
1956d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o	if (I_flag && !io_ptr_orig) {
1957d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o		/*
1958d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o		 * Check the inode size is right so we can issue an
1959d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o		 * error message and bail before setting up the tdb
1960d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o		 * file.
1961d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o		 */
1962d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o		if (new_inode_size == EXT2_INODE_SIZE(fs->super)) {
19639266fc7a2fe49c6de871016772a2120830e183a9Theodore Ts'o			fprintf(stderr, _("The inode size is already %lu\n"),
1964d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o				new_inode_size);
1965e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			rc = 1;
1966e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goto closefs;
1967d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o		}
1968d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o		if (new_inode_size < EXT2_INODE_SIZE(fs->super)) {
1969e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			fprintf(stderr, "%s",
1970e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				_("Shrinking inode size is not supported\n"));
1971e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			rc = 1;
1972e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goto closefs;
1973e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
1974e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (new_inode_size > fs->blocksize) {
1975e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			fprintf(stderr, _("Invalid inode size %lu (max %d)\n"),
1976e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				new_inode_size, fs->blocksize);
1977e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			rc = 1;
1978e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goto closefs;
1979d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o		}
1980d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o
1981d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o		/*
1982d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o		 * If inode resize is requested use the
1983d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o		 * Undo I/O manager
1984d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o		 */
1985d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o		io_ptr_orig = io_ptr;
1986d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o		retval = tune2fs_setup_tdb(device_name, &io_ptr);
1987e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (retval) {
1988e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			rc = 1;
1989e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goto closefs;
1990e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
1991d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o		if (io_ptr != io_ptr_orig) {
1992d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o			ext2fs_close(fs);
1993d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o			goto retry_open;
1994d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o		}
1995d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o	}
1996d887f88d220317aa05e6007be9eb19a3b654ece2Theodore Ts'o
1997832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o	sb = fs->super;
1998058ad1c70c9a097d282270c6f76d3c3493e15fe2Theodore Ts'o	fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
19992be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o
2000832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o	if (print_label) {
2001832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o		/* For e2label emulation */
2002c8c071a07319939dfd7ae2ff1dedec644d750debTheodore Ts'o		printf("%.*s\n", (int) sizeof(sb->s_volume_name),
2003c8c071a07319939dfd7ae2ff1dedec644d750debTheodore Ts'o		       sb->s_volume_name);
2004a6d8302b4873527798a77c1ba3106a04b71dfeacTheodore Ts'o		remove_error_table(&et_ext2_error_table);
2005e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		goto closefs;
2006832381536ee28ea493b73785f7c0cfdd403a8269Theodore Ts'o	}
20072be8fe43976537b75a6ee154ff3ba47e538b55fbTheodore Ts'o
2008d06863f0e5db501366cf55c85d8e26de1fa4fcc6Theodore Ts'o	retval = ext2fs_check_if_mounted(device_name, &mount_flags);
2009d06863f0e5db501366cf55c85d8e26de1fa4fcc6Theodore Ts'o	if (retval) {
2010d06863f0e5db501366cf55c85d8e26de1fa4fcc6Theodore Ts'o		com_err("ext2fs_check_if_mount", retval,
2011d06863f0e5db501366cf55c85d8e26de1fa4fcc6Theodore Ts'o			_("while determining whether %s is mounted."),
2012d06863f0e5db501366cf55c85d8e26de1fa4fcc6Theodore Ts'o			device_name);
2013e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		rc = 1;
2014e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		goto closefs;
2015b21e38a0df0111f527f7b286ff9119534de04c09Theodore Ts'o	}
201663985320384bf143eaac9857af424800d9867a1aTheodore Ts'o	/* Normally we only need to write out the superblock */
201763985320384bf143eaac9857af424800d9867a1aTheodore Ts'o	fs->flags |= EXT2_FLAG_SUPER_ONLY;
20183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
20191e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	if (c_flag) {
2020b21e38a0df0111f527f7b286ff9119534de04c09Theodore Ts'o		sb->s_max_mnt_count = max_mount_count;
20213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		ext2fs_mark_super_dirty(fs);
2022ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		printf(_("Setting maximal mount count to %d\n"),
2023ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		       max_mount_count);
20243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
20251e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	if (C_flag) {
2026b21e38a0df0111f527f7b286ff9119534de04c09Theodore Ts'o		sb->s_mnt_count = mount_count;
20271e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		ext2fs_mark_super_dirty(fs);
2028ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		printf(_("Setting current mount count to %d\n"), mount_count);
20291e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	}
20301e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	if (e_flag) {
2031b21e38a0df0111f527f7b286ff9119534de04c09Theodore Ts'o		sb->s_errors = errors;
20323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		ext2fs_mark_super_dirty(fs);
2033ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		printf(_("Setting error behavior to %d\n"), errors);
20343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
2035b21e38a0df0111f527f7b286ff9119534de04c09Theodore Ts'o	if (g_flag) {
2036b21e38a0df0111f527f7b286ff9119534de04c09Theodore Ts'o		sb->s_def_resgid = resgid;
2037f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		ext2fs_mark_super_dirty(fs);
2038ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		printf(_("Setting reserved blocks gid to %lu\n"), resgid);
2039f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	}
2040818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'o	if (i_flag) {
2041e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (interval >= (1ULL << 32)) {
2042e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			com_err(program_name, 0,
2043e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				_("interval between checks is too big (%lu)"),
2044e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				interval);
2045e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			rc = 1;
2046e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goto closefs;
2047e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
2048b21e38a0df0111f527f7b286ff9119534de04c09Theodore Ts'o		sb->s_checkinterval = interval;
20493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		ext2fs_mark_super_dirty(fs);
2050ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		printf(_("Setting interval between checks to %lu seconds\n"),
2051ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		       interval);
20523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
2053818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'o	if (m_flag) {
2054e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_r_blocks_count_set(sb, reserved_ratio *
2055e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					  ext2fs_blocks_count(sb) / 100.0);
20563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		ext2fs_mark_super_dirty(fs);
2057e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		printf (_("Setting reserved blocks percentage to %g%% (%llu blocks)\n"),
2058e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			reserved_ratio, ext2fs_r_blocks_count(sb));
20593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
2060818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'o	if (r_flag) {
2061e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (reserved_blocks > ext2fs_blocks_count(sb)/2) {
2062ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			com_err(program_name, 0,
2063e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				_("reserved blocks count is too big (%llu)"),
2064ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				reserved_blocks);
2065e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			rc = 1;
2066e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goto closefs;
2067f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		}
2068e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_r_blocks_count_set(sb, reserved_blocks);
2069f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		ext2fs_mark_super_dirty(fs);
2070e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		printf(_("Setting reserved blocks count to %llu\n"),
2071ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		       reserved_blocks);
2072f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	}
2073521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o	if (s_flag == 1) {
2074521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o		if (sb->s_feature_ro_compat &
2075521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o		    EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)
2076544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o			fputs(_("\nThe filesystem already has sparse "
2077544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o				"superblocks.\n"), stderr);
2078521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o		else {
2079521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o			sb->s_feature_ro_compat |=
2080521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o				EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
2081b21e38a0df0111f527f7b286ff9119534de04c09Theodore Ts'o			sb->s_state &= ~EXT2_VALID_FS;
2082521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o			ext2fs_mark_super_dirty(fs);
2083d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o			printf(_("\nSparse superblock flag set.  %s"),
2084a4fa100c5b743491f33b77981c4bf28ba4fe1e34Theodore Ts'o			       _(please_fsck));
2085521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o		}
2086521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o	}
2087521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o	if (s_flag == 0) {
2088ff662d5dbf95f2e68eed6f6b6a4e10307a7d13bdTheodore Ts'o		fputs(_("\nClearing the sparse superflag not supported.\n"),
2089ff662d5dbf95f2e68eed6f6b6a4e10307a7d13bdTheodore Ts'o		      stderr);
2090e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		rc = 1;
2091e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		goto closefs;
2092521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o	}
2093d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o	if (T_flag) {
2094d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o		sb->s_lastcheck = last_check_time;
2095d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o		ext2fs_mark_super_dirty(fs);
2096d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o		printf(_("Setting time filesystem last checked to %s\n"),
2097d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o		       ctime(&last_check_time));
2098d4de4aa938339275515b2b5b6fcf8ca2b51c3d34Theodore Ts'o	}
2099b21e38a0df0111f527f7b286ff9119534de04c09Theodore Ts'o	if (u_flag) {
2100b21e38a0df0111f527f7b286ff9119534de04c09Theodore Ts'o		sb->s_def_resuid = resuid;
2101f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		ext2fs_mark_super_dirty(fs);
2102ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		printf(_("Setting reserved blocks uid to %lu\n"), resuid);
2103f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	}
21041e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	if (L_flag) {
2105a789d8406070224503c9ab78040acc7ea80c65aeTheodore Ts'o		if (strlen(new_label) > sizeof(sb->s_volume_name))
2106efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o			fputs(_("Warning: label too long, truncating.\n"),
2107544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o			      stderr);
21081e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		memset(sb->s_volume_name, 0, sizeof(sb->s_volume_name));
21091e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		strncpy(sb->s_volume_name, new_label,
21101e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o			sizeof(sb->s_volume_name));
21111e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		ext2fs_mark_super_dirty(fs);
21121e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	}
21131e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	if (M_flag) {
21141e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		memset(sb->s_last_mounted, 0, sizeof(sb->s_last_mounted));
21151e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		strncpy(sb->s_last_mounted, new_last_mounted,
21161e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o			sizeof(sb->s_last_mounted));
21171e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		ext2fs_mark_super_dirty(fs);
21181e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	}
2119e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (mntopts_cmd) {
2120e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		rc = update_mntopts(fs, mntopts_cmd);
2121e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (rc)
2122e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goto closefs;
2123e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
2124e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (features_cmd) {
2125e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		rc = update_feature_set(fs, features_cmd);
2126e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (rc)
2127e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goto closefs;
2128e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
2129e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (extended_cmd) {
2130e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		rc = parse_extended_opts(fs, extended_cmd);
2131e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (rc)
2132e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goto closefs;
2133e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (clear_mmp && !f_flag) {
2134e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			fputs(_("Error in using clear_mmp. "
2135e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				"It must be used with -f\n"),
2136e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			      stderr);
2137e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goto closefs;
2138e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
2139e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
2140e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (clear_mmp) {
2141e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		rc = ext2fs_mmp_clear(fs);
2142e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		goto closefs;
2143e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
2144e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (journal_size || journal_device) {
2145e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		rc = add_journal(fs);
2146e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (rc)
2147e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goto closefs;
2148e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
2149e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
2150e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (Q_flag) {
2151e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (mount_flags & EXT2_MF_MOUNTED) {
2152e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			fputs(_("The quota feature may only be changed when "
2153e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				"the filesystem is unmounted.\n"), stderr);
2154e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			rc = 1;
2155e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goto closefs;
2156e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
2157e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		handle_quota_options(fs);
2158e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
2159771e8db9f04da550ee7c0ca74b198e989ea4ff35Aditya Kali
21601e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	if (U_flag) {
21619d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o		int set_csum = 0;
21629d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o		dgrp_t i;
21639d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o
21649d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o		if (sb->s_feature_ro_compat &
21659d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o		    EXT4_FEATURE_RO_COMPAT_GDT_CSUM) {
2166ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			/*
2167e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			 * Changing the UUID requires rewriting all metadata,
2168e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			 * which can race with a mounted fs.  Don't allow that.
2169e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			 */
2170e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			if (mount_flags & EXT2_MF_MOUNTED) {
2171e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				fputs(_("The UUID may only be "
2172e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					"changed when the filesystem is "
2173e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					"unmounted.\n"), stderr);
2174e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				exit(1);
2175e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			}
2176e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			if (check_fsck_needed(fs))
2177e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				exit(1);
2178e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
2179e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			/*
21809d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o			 * Determine if the block group checksums are
21819d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o			 * correct so we know whether or not to set
21829d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o			 * them later on.
21839d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o			 */
21849d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o			for (i = 0; i < fs->group_desc_count; i++)
21859d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o				if (!ext2fs_group_desc_csum_verify(fs, i))
21869d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o					break;
21879d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o			if (i >= fs->group_desc_count)
21889d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o				set_csum = 1;
21899d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o		}
21904d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o		if ((strcasecmp(new_UUID, "null") == 0) ||
21914d0f22832cf02183e001ce9dd94787aaf2ff1ec9Theodore Ts'o		    (strcasecmp(new_UUID, "clear") == 0)) {
21921e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o			uuid_clear(sb->s_uuid);
219363985320384bf143eaac9857af424800d9867a1aTheodore Ts'o		} else if (strcasecmp(new_UUID, "time") == 0) {
219463985320384bf143eaac9857af424800d9867a1aTheodore Ts'o			uuid_generate_time(sb->s_uuid);
21951e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		} else if (strcasecmp(new_UUID, "random") == 0) {
21961e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o			uuid_generate(sb->s_uuid);
21971e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		} else if (uuid_parse(new_UUID, sb->s_uuid)) {
2198e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			com_err(program_name, 0, "%s",
2199e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				_("Invalid UUID format\n"));
2200e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			rc = 1;
2201e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goto closefs;
22021e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		}
22039d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o		if (set_csum) {
22049d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o			for (i = 0; i < fs->group_desc_count; i++)
22059d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o				ext2fs_group_desc_csum_set(fs, i);
22069d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o			fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
22079d4a4dc2870c46c74f815ec2bebe10b4701accf2Theodore Ts'o		}
22081e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		ext2fs_mark_super_dirty(fs);
22091e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	}
221064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	if (I_flag) {
221164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		if (mount_flags & EXT2_MF_MOUNTED) {
221264d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V			fputs(_("The inode size may only be "
221364d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V				"changed when the filesystem is "
221464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V				"unmounted.\n"), stderr);
2215e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			rc = 1;
2216e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goto closefs;
221764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		}
22185bf81baea01a19ce48daee5db07f08c6a9655ab5Theodore Ts'o		if (fs->super->s_feature_incompat &
22195bf81baea01a19ce48daee5db07f08c6a9655ab5Theodore Ts'o		    EXT4_FEATURE_INCOMPAT_FLEX_BG) {
2220ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			fputs(_("Changing the inode size not supported for "
2221ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				"filesystems with the flex_bg\n"
2222ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o				"feature enabled.\n"),
22235bf81baea01a19ce48daee5db07f08c6a9655ab5Theodore Ts'o			      stderr);
2224e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			rc = 1;
2225e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goto closefs;
22265bf81baea01a19ce48daee5db07f08c6a9655ab5Theodore Ts'o		}
222764d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		/*
222864d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		 * We want to update group descriptor also
222964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		 * with the new free inode count
223064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		 */
223164d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
2232a9e5177be906eb9b22a67f7703e1fe10da231c49Aneesh Kumar K.V		if (resize_inode(fs, new_inode_size) == 0) {
2233ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o			printf(_("Setting inode size %lu\n"),
223464d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V							new_inode_size);
2235e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		} else {
2236e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			printf("%s", _("Failed to change inode size\n"));
2237e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			rc = 1;
2238e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			goto closefs;
223964d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V		}
224064d588cfeac8f0125b2a29c8b61320ddab267391Aneesh Kumar K.V	}
22411e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o
22423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (l_flag)
2243ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o		list_super(sb);
22440c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o	if (stride_set) {
22450c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o		sb->s_raid_stride = stride;
22460c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o		ext2fs_mark_super_dirty(fs);
22470c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o		printf(_("Setting stride size to %d\n"), stride);
22480c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o	}
22490c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o	if (stripe_width_set) {
22500c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o		sb->s_raid_stripe_width = stripe_width;
22510c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o		ext2fs_mark_super_dirty(fs);
22520c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o		printf(_("Setting stripe width to %d\n"), stripe_width);
22530c17cb25f24730dca138a976a390f105d2191736Theodore Ts'o	}
2254e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (ext_mount_opts) {
2255e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		strncpy((char *)(fs->super->s_mount_opts), ext_mount_opts,
2256e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			sizeof(fs->super->s_mount_opts));
2257e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		fs->super->s_mount_opts[sizeof(fs->super->s_mount_opts)-1] = 0;
2258e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_mark_super_dirty(fs);
2259e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		printf(_("Setting extended default mount options to '%s'\n"),
2260e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		       ext_mount_opts);
2261e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		free(ext_mount_opts);
2262e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
22631acde2b2776fca4d9386a04909296c2e6b11f242Theodore Ts'o	free(device_name);
2264a6d8302b4873527798a77c1ba3106a04b71dfeacTheodore Ts'o	remove_error_table(&et_ext2_error_table);
2265e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
2266e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallclosefs:
2267d25948b9b4a9e361ef071dc8175df0407f60b7e0JP Abgrallif (rc) {
2268e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_mmp_stop(fs);
2269d25948b9b4a9e361ef071dc8175df0407f60b7e0JP Abgrall#ifndef BUILD_AS_LIB
2270e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		exit(1);
2271d25948b9b4a9e361ef071dc8175df0407f60b7e0JP Abgrall#endif
2272e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
2273ec43da2f35c54589e8aa0663d9cf44f86895242aTheodore Ts'o	return (ext2fs_close(fs) ? 1 : 0);
22743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
2275