13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
23839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * debugfs.c --- a program which allows you to attach an ext2fs
33839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * filesystem and play with it.
43839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o *
53839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Copyright (C) 1993 Theodore Ts'o.  This file may be redistributed
63839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * under the terms of the GNU Public License.
7efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
83839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Modifications by Robert Sanders <gt8134b@prism.gatech.edu>
93839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
11d1154eb460efe588eaed3d439c1caaca149fa362Theodore Ts'o#include "config.h"
123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h>
133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <unistd.h>
143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdlib.h>
153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <ctype.h>
163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <string.h>
173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <time.h>
18491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong#include <libgen.h>
1950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_GETOPT_H
203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <getopt.h>
21efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o#else
2250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oextern int optind;
2350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oextern char *optarg;
2450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif
2550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_ERRNO_H
2650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <errno.h>
2750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif
2850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <fcntl.h>
293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "debugfs.h"
31fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o#include "uuid/uuid.h"
32f68aa41476b0d7f43e85413fd08d7cfc8f916ea6Theodore Ts'o#include "e2p/e2p.h"
333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
34ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o#include <ext2fs/ext2_ext_attr.h>
35ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o
36818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'o#include "../version.h"
3703efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger#include "jfs_user.h"
3899ceb8ec1acd7f38da289966b9984b3ffa1914a9Theodore Ts'o#include "support/plausible.h"
39818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'o
40355ffb2ff566229b8bc3f5f7557e91edff5a767aRobert Yang#ifndef BUFSIZ
41355ffb2ff566229b8bc3f5f7557e91edff5a767aRobert Yang#define BUFSIZ 8192
42355ffb2ff566229b8bc3f5f7557e91edff5a767aRobert Yang#endif
43355ffb2ff566229b8bc3f5f7557e91edff5a767aRobert Yang
441fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o#ifdef CONFIG_JBD_DEBUG		/* Enabled by configure --enable-jbd-debug */
451fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'oint journal_enable_debug = -1;
461fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o#endif
471fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o
4849ce6cb5cee956a478a3704c92619de1c7f204d5Theodore Ts'oss_request_table *extra_cmds;
492d328bb76d2d63bdfdba923b54c28bd686bd8fecTheodore Ts'oconst char *debug_prog_name;
50bee7b67ce92bb912fccc0dcce3c71c186c2a988bTheodore Ts'oint sci_idx;
513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
52ba08cb996a10a8f5e72625ed054cb029571d84e0Theodore Ts'oext2_filsys	current_fs;
5375fc42f1a1fa98a722540e6a2761be17126dd080Theodore Ts'oquota_ctx_t	current_qctx;
54b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'oext2_ino_t	root, cwd;
553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
56491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wongstatic int debugfs_setup_tdb(const char *device_name, char *undo_file,
57491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong			     io_manager *io_ptr)
58491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong{
59491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	errcode_t retval = ENOMEM;
60491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	char *tdb_dir = NULL, *tdb_file = NULL;
61491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	char *dev_name, *tmp_name;
62491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong
63491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	/* (re)open a specific undo file */
64491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	if (undo_file && undo_file[0] != 0) {
65b0851392244e2a87cad67739d86c7489d4db3222Darrick J. Wong		retval = set_undo_io_backing_manager(*io_ptr);
66b0851392244e2a87cad67739d86c7489d4db3222Darrick J. Wong		if (retval)
67b0851392244e2a87cad67739d86c7489d4db3222Darrick J. Wong			goto err;
68491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong		*io_ptr = undo_io_manager;
69491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong		retval = set_undo_io_backup_file(undo_file);
70491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong		if (retval)
71491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong			goto err;
72491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong		printf("Overwriting existing filesystem; this can be undone "
73491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong			"using the command:\n"
74491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong			"    e2undo %s %s\n\n",
75491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong			undo_file, device_name);
76b0851392244e2a87cad67739d86c7489d4db3222Darrick J. Wong		return retval;
77491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	}
78491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong
79491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	/*
80491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	 * Configuration via a conf file would be
81491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	 * nice
82491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	 */
831fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o	tdb_dir = ss_safe_getenv("E2FSPROGS_UNDO_DIR");
84b0851392244e2a87cad67739d86c7489d4db3222Darrick J. Wong	if (!tdb_dir)
85b0851392244e2a87cad67739d86c7489d4db3222Darrick J. Wong		tdb_dir = "/var/lib/e2fsprogs";
86491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong
87b0851392244e2a87cad67739d86c7489d4db3222Darrick J. Wong	if (!strcmp(tdb_dir, "none") || (tdb_dir[0] == 0) ||
88b0851392244e2a87cad67739d86c7489d4db3222Darrick J. Wong	    access(tdb_dir, W_OK))
89491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong		return 0;
90491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong
91491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	tmp_name = strdup(device_name);
92491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	if (!tmp_name)
93491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong		goto errout;
94491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	dev_name = basename(tmp_name);
95b0851392244e2a87cad67739d86c7489d4db3222Darrick J. Wong	tdb_file = malloc(strlen(tdb_dir) + 9 + strlen(dev_name) + 7 + 1);
96491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	if (!tdb_file) {
97491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong		free(tmp_name);
98491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong		goto errout;
99491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	}
100491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	sprintf(tdb_file, "%s/debugfs-%s.e2undo", tdb_dir, dev_name);
101491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	free(tmp_name);
102491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong
103491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	if ((unlink(tdb_file) < 0) && (errno != ENOENT)) {
104491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong		retval = errno;
105b0851392244e2a87cad67739d86c7489d4db3222Darrick J. Wong		com_err("debugfs", retval,
106b0851392244e2a87cad67739d86c7489d4db3222Darrick J. Wong			"while trying to delete %s", tdb_file);
107491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong		goto errout;
108491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	}
109491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong
110b0851392244e2a87cad67739d86c7489d4db3222Darrick J. Wong	retval = set_undo_io_backing_manager(*io_ptr);
111b0851392244e2a87cad67739d86c7489d4db3222Darrick J. Wong	if (retval)
112b0851392244e2a87cad67739d86c7489d4db3222Darrick J. Wong		goto errout;
113491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	*io_ptr = undo_io_manager;
114491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	retval = set_undo_io_backup_file(tdb_file);
115491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	if (retval)
116491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong		goto errout;
117491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	printf("Overwriting existing filesystem; this can be undone "
118491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong		"using the command:\n"
119491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong		"    e2undo %s %s\n\n", tdb_file, device_name);
120491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong
121491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	free(tdb_file);
122491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	return 0;
123491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wongerrout:
124491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	free(tdb_file);
125491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wongerr:
126491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	com_err("debugfs", retval, "while trying to setup undo file\n");
127491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	return retval;
128491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong}
129491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong
130048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Hensonstatic void open_filesystem(char *device, int open_flags, blk64_t superblock,
131048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			    blk64_t blocksize, int catastrophic,
132491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong			    char *data_filename, char *undo_file)
1333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int	retval;
1351ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o	io_channel data_io = 0;
136491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	io_manager io_ptr = unix_io_manager;
1372e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o
1382e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o	if (superblock != 0 && blocksize == 0) {
1392e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		com_err(device, 0, "if you specify the superblock, you must also specify the block size");
1402e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		current_fs = NULL;
1412e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		return;
1422e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o	}
1432e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o
1441ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o	if (data_filename) {
1451ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o		if ((open_flags & EXT2_FLAG_IMAGE_FILE) == 0) {
146efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o			com_err(device, 0,
1471ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o				"The -d option is only valid when reading an e2image file");
1481ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o			current_fs = NULL;
1491ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o			return;
1501ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o		}
1511ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o		retval = unix_io_manager->open(data_filename, 0, &data_io);
1521ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o		if (retval) {
1531ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o			com_err(data_filename, 0, "while opening data source");
1541ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o			current_fs = NULL;
1551ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o			return;
1561ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o		}
1571ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o	}
1581ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o
1592e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o	if (catastrophic && (open_flags & EXT2_FLAG_RW)) {
1602e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		com_err(device, 0,
1612e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o			"opening read-only because of catastrophic mode");
1622e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		open_flags &= ~EXT2_FLAG_RW;
1632e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o	}
1640f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger	if (catastrophic)
1650f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger		open_flags |= EXT2_FLAG_SKIP_MMP;
166efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
167491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	if (undo_file) {
168491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong		retval = debugfs_setup_tdb(device, undo_file, &io_ptr);
169491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong		if (retval)
170491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong			exit(1);
171491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	}
172491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong
1732e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o	retval = ext2fs_open(device, open_flags, superblock, blocksize,
174491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong			     io_ptr, &current_fs);
1753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (retval) {
1763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		com_err(device, retval, "while opening filesystem");
177c8b20b40ebf0278b2d100a964a32d8e13046f437Darrick J. Wong		if (retval == EXT2_ET_BAD_MAGIC)
178c8b20b40ebf0278b2d100a964a32d8e13046f437Darrick J. Wong			check_plausibility(device, CHECK_FS_EXIST, NULL);
179fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		current_fs = NULL;
1803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
1813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
18224dea55494ea753dbc8e4d965345cd2a7144d4fdTheodore Ts'o	current_fs->default_bitmap_type = EXT2FS_BMAP64_RBTREE;
1832e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o
1842e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o	if (catastrophic)
1852e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		com_err(device, 0, "catastrophic mode - not reading inode or group bitmaps");
1862e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o	else {
1872e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		retval = ext2fs_read_inode_bitmap(current_fs);
1882e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		if (retval) {
1892e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o			com_err(device, retval, "while reading inode bitmap");
1902e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o			goto errout;
1912e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		}
1922e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		retval = ext2fs_read_block_bitmap(current_fs);
1932e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		if (retval) {
1942e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o			com_err(device, retval, "while reading block bitmap");
1952e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o			goto errout;
1962e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		}
1973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1981ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o
1991ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o	if (data_io) {
2001ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o		retval = ext2fs_set_data_io(current_fs, data_io);
2011ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o		if (retval) {
202efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o			com_err(device, retval,
2031ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o				"while setting data source");
2041ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o			goto errout;
2051ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o		}
2061ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o	}
2071ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o
2083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	root = cwd = EXT2_ROOT_INO;
2093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return;
2103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
2113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oerrout:
21247fee2ef6a23ae06f680336ffde57caa64604a4cLukas Czerner	retval = ext2fs_close_free(&current_fs);
2133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (retval)
2143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		com_err(device, retval, "while trying to close filesystem");
2153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
2163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
2173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_open_filesys(int argc, char **argv)
2183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
219e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	int	c, err;
2202e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o	int	catastrophic = 0;
221048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	blk64_t	superblock = 0;
222048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	blk64_t	blocksize = 0;
22303b9dca63a75731711071e0a7ddef0475d6daf3aEric Sandeen	int	open_flags = EXT2_FLAG_SOFTSUPP_FEATURES | EXT2_FLAG_64BITS;
224b0d17e0d47f072c208633f8cad0fbe123faf2876Theodore Ts'o	char	*data_filename = 0;
225491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	char	*undo_file = NULL;
226efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
22788494bb6d440f703db98b6cc4452f63d7aa392b9Theodore Ts'o	reset_getopt();
228491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	while ((c = getopt(argc, argv, "iwfecb:s:d:Dz:")) != EOF) {
2293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		switch (c) {
23059cf7e0da802aa8f560434bd521c30f5bb5d3e21Theodore Ts'o		case 'i':
23159cf7e0da802aa8f560434bd521c30f5bb5d3e21Theodore Ts'o			open_flags |= EXT2_FLAG_IMAGE_FILE;
23259cf7e0da802aa8f560434bd521c30f5bb5d3e21Theodore Ts'o			break;
2333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		case 'w':
234e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#ifdef READ_ONLY
235e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o			goto print_usage;
236e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#else
237d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o			open_flags |= EXT2_FLAG_RW;
238e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#endif /* READ_ONLY */
239d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o			break;
240d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o		case 'f':
241d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o			open_flags |= EXT2_FLAG_FORCE;
2423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			break;
24398eb44bdb5749f323a858d71bf5e7f0eddb61191Theodore Ts'o		case 'e':
24498eb44bdb5749f323a858d71bf5e7f0eddb61191Theodore Ts'o			open_flags |= EXT2_FLAG_EXCLUSIVE;
24598eb44bdb5749f323a858d71bf5e7f0eddb61191Theodore Ts'o			break;
2462e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		case 'c':
2472e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o			catastrophic = 1;
2482e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o			break;
2491ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o		case 'd':
2501ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o			data_filename = optarg;
2511ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o			break;
2520fd68e0241e944545d43045593e82b0fb7317797Theodore Ts'o		case 'D':
2530fd68e0241e944545d43045593e82b0fb7317797Theodore Ts'o			open_flags |= EXT2_FLAG_DIRECT_IO;
2540fd68e0241e944545d43045593e82b0fb7317797Theodore Ts'o			break;
2552e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		case 'b':
256e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o			blocksize = parse_ulong(optarg, argv[0],
257e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o						"block size", &err);
258e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o			if (err)
2592e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o				return;
2602e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o			break;
2612e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		case 's':
262a25fffae5cbdb9349fa3c358c9714584e9de7b33Eric Whitney			err = strtoblk(argv[0], optarg,
263a25fffae5cbdb9349fa3c358c9714584e9de7b33Eric Whitney				       "superblock block number", &superblock);
264e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o			if (err)
2652e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o				return;
2662e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o			break;
267491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong		case 'z':
268491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong			undo_file = optarg;
269491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong			break;
2703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		default:
2719b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o			goto print_usage;
2723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
2733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
2743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (optind != argc-1) {
2759b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o		goto print_usage;
2763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
2773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (check_fs_not_open(argv[0]))
2783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
2792e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o	open_filesystem(argv[optind], open_flags,
280efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o			superblock, blocksize, catastrophic,
281491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong			data_filename, undo_file);
2829b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o	return;
2839b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o
2849b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'oprint_usage:
2855093775ab446d375ea753218c364be31cf82f3ccZheng Liu	fprintf(stderr, "%s: Usage: open [-s superblock] [-b blocksize] "
2865093775ab446d375ea753218c364be31cf82f3ccZheng Liu		"[-d image_filename] [-c] [-i] [-f] [-e] [-D] "
287e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#ifndef READ_ONLY
288e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o		"[-w] "
289e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#endif
290e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o		"<device>\n", argv[0]);
2912e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o}
2922e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o
2932e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'ovoid do_lcd(int argc, char **argv)
2942e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o{
29557a1cbb643237b168bd4151aff3d3bad28bbc326Theodore Ts'o	if (argc != 2) {
29657a1cbb643237b168bd4151aff3d3bad28bbc326Theodore Ts'o		com_err(argv[0], 0, "Usage: %s %s", argv[0], "<native dir>");
2972e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		return;
29857a1cbb643237b168bd4151aff3d3bad28bbc326Theodore Ts'o	}
2992e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o
3002e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o	if (chdir(argv[1]) == -1) {
3012e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		com_err(argv[0], errno,
3022e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o			"while trying to change native directory to %s",
3032e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o			argv[1]);
3042e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		return;
3052e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o	}
3063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
3073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
30850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'ostatic void close_filesystem(NOARGS)
3093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
3103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int	retval;
311efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
312fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	if (current_fs->flags & EXT2_FLAG_IB_DIRTY) {
313fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		retval = ext2fs_write_inode_bitmap(current_fs);
3143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (retval)
3159b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o			com_err("ext2fs_write_inode_bitmap", retval, 0);
3163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
317fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	if (current_fs->flags & EXT2_FLAG_BB_DIRTY) {
318fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		retval = ext2fs_write_block_bitmap(current_fs);
3193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (retval)
3209b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o			com_err("ext2fs_write_block_bitmap", retval, 0);
3213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
32275fc42f1a1fa98a722540e6a2761be17126dd080Theodore Ts'o	if (current_qctx)
32375fc42f1a1fa98a722540e6a2761be17126dd080Theodore Ts'o		quota_release_context(&current_qctx);
32447fee2ef6a23ae06f680336ffde57caa64604a4cLukas Czerner	retval = ext2fs_close_free(&current_fs);
3253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (retval)
3269b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o		com_err("ext2fs_close", retval, 0);
3273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return;
3283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
3293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
3303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_close_filesys(int argc, char **argv)
3313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
3326dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o	int	c;
3336dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o
3346dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o	if (check_fs_open(argv[0]))
3353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
3366dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o
3376dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o	reset_getopt();
3386dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o	while ((c = getopt (argc, argv, "a")) != EOF) {
3396dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o		switch (c) {
3406dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o		case 'a':
3416dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o			current_fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
3426dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o			break;
3436dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o		default:
3446dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o			goto print_usage;
3456dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o		}
3466dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o	}
3476dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o
3486dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o	if (argc > optind) {
3496dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o	print_usage:
3506dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o		com_err(0, 0, "Usage: close_filesys [-a]");
3516dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o		return;
3526dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o	}
3536dce532867a0f8d6a99a2c6fe049de411dc109f2Theodore Ts'o
3543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	close_filesystem();
3553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
3563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
357e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#ifndef READ_ONLY
3583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_init_filesys(int argc, char **argv)
3593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
3603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	struct ext2_super_block param;
3613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	errcode_t	retval;
362e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	int		err;
363fe56188b07668758c28912b6eaf31abb498a9e82Darrick J. Wong	blk64_t		blocks;
364efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
365e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (common_args_process(argc, argv, 3, 3, "initialize",
36657d4fb66d237fd8b734d2aa6b13502fac9c6e5a3Darrick J. Wong				"<device> <blocks>", CHECK_FS_NOTOPEN))
3673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
3683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
3693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	memset(&param, 0, sizeof(struct ext2_super_block));
370a25fffae5cbdb9349fa3c358c9714584e9de7b33Eric Whitney	err = strtoblk(argv[0], argv[2], "blocks count", &blocks);
371fe56188b07668758c28912b6eaf31abb498a9e82Darrick J. Wong	if (err)
372fe56188b07668758c28912b6eaf31abb498a9e82Darrick J. Wong		return;
373fe56188b07668758c28912b6eaf31abb498a9e82Darrick J. Wong	ext2fs_blocks_count_set(&param, blocks);
374fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	retval = ext2fs_initialize(argv[1], 0, &param,
375fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o				   unix_io_manager, &current_fs);
3763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (retval) {
3773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		com_err(argv[1], retval, "while initializing filesystem");
378fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		current_fs = NULL;
3793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
3803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
3813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	root = cwd = EXT2_ROOT_INO;
3823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return;
3833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
3843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
3855dd8f963d04fa4099a003cb3b13ffae05ab29210Theodore Ts'ostatic void print_features(struct ext2_super_block * s, FILE *f)
386d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o{
387d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o	int	i, j, printed=0;
388092c3dec39301ac61367b710d995f74b523948c2Theodore Ts'o	__u32	*mask = &s->s_feature_compat, m;
389d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o
390777ebb3e51b1c7ec0d7c5a457ef04d40f61b6c30Theodore Ts'o	fputs("Filesystem features:", f);
391d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o	for (i=0; i <3; i++,mask++) {
392d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o		for (j=0,m=1; j < 32; j++, m<<=1) {
393d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o			if (*mask & m) {
394d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o				fprintf(f, " %s", e2p_feature2string(i, m));
395d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o				printed++;
396d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o			}
397d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o		}
398d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o	}
399d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o	if (printed == 0)
400777ebb3e51b1c7ec0d7c5a457ef04d40f61b6c30Theodore Ts'o		fputs("(none)", f);
401777ebb3e51b1c7ec0d7c5a457ef04d40f61b6c30Theodore Ts'o	fputs("\n", f);
402d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o}
4033cebf9c1029ca983ebbbae79f7905a02d087ff98Theodore Ts'o#endif /* READ_ONLY */
404d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o
405732c8cd58ff30ffae0d3276c411a08920717a46cTheodore Ts'ostatic void print_bg_opts(ext2_filsys fs, dgrp_t group, int mask,
406f5fa20078bfc05b554294fe9c5505375d7913e8cTheodore Ts'o			  const char *str, int *first, FILE *f)
407f5fa20078bfc05b554294fe9c5505375d7913e8cTheodore Ts'o{
408cd65a24e756b8f6770a5961fd94c67eb00dd7baaTheodore Ts'o	if (ext2fs_bg_flags_test(fs, group, mask)) {
409f5fa20078bfc05b554294fe9c5505375d7913e8cTheodore Ts'o		if (*first) {
410f5fa20078bfc05b554294fe9c5505375d7913e8cTheodore Ts'o			fputs("           [", f);
411f5fa20078bfc05b554294fe9c5505375d7913e8cTheodore Ts'o			*first = 0;
412f5fa20078bfc05b554294fe9c5505375d7913e8cTheodore Ts'o		} else
413f5fa20078bfc05b554294fe9c5505375d7913e8cTheodore Ts'o			fputs(", ", f);
414f5fa20078bfc05b554294fe9c5505375d7913e8cTheodore Ts'o		fputs(str, f);
415f5fa20078bfc05b554294fe9c5505375d7913e8cTheodore Ts'o	}
416f5fa20078bfc05b554294fe9c5505375d7913e8cTheodore Ts'o}
417f5fa20078bfc05b554294fe9c5505375d7913e8cTheodore Ts'o
4183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_show_super_stats(int argc, char *argv[])
4193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
4202418dfd7b934ee6bf3dc9a0aa4ffee8b37f4384fTheodore Ts'o	const char *units ="block";
421544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o	dgrp_t	i;
4223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	FILE 	*out;
423d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o	int	c, header_only = 0;
4248fdf29117f922419bd5b3f741e5d554b1d5b8893Jose R. Santos	int	numdirs = 0, first, gdt_csum;
4258fdf29117f922419bd5b3f741e5d554b1d5b8893Jose R. Santos
42688494bb6d440f703db98b6cc4452f63d7aa392b9Theodore Ts'o	reset_getopt();
427d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o	while ((c = getopt (argc, argv, "h")) != EOF) {
428d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o		switch (c) {
429d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o		case 'h':
430d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o			header_only++;
431d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o			break;
432d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o		default:
4339b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o			goto print_usage;
434d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o		}
435d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o	}
436d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o	if (optind != argc) {
4379b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o		goto print_usage;
4383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
4393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (check_fs_open(argv[0]))
4403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
4413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	out = open_pager();
442bd09eff9b2caaa3539c3ed119a067782714bffa2Theodore Ts'o
4434ee26699823c945b1894880f53cea3b45b5e3a20Darrick J. Wong	if (ext2fs_has_feature_bigalloc(current_fs->super))
4442418dfd7b934ee6bf3dc9a0aa4ffee8b37f4384fTheodore Ts'o		units = "cluster";
4452418dfd7b934ee6bf3dc9a0aa4ffee8b37f4384fTheodore Ts'o
446bd09eff9b2caaa3539c3ed119a067782714bffa2Theodore Ts'o	list_super2(current_fs->super, out);
44734be9609de977fe2e041c7b48fb9d4d0d6878bb1Theodore Ts'o	for (i=0; i < current_fs->group_desc_count; i++)
448048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		numdirs += ext2fs_bg_used_dirs_count(current_fs, i);
44934be9609de977fe2e041c7b48fb9d4d0d6878bb1Theodore Ts'o	fprintf(out, "Directories:              %d\n", numdirs);
450efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
451d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o	if (header_only) {
452d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o		close_pager(out);
453d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o		return;
454d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o	}
455efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
4565b58dc2304f06953e1d8314ea570cc3befec95bcDarrick J. Wong	gdt_csum = ext2fs_has_group_desc_csum(current_fs);
457048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	for (i = 0; i < current_fs->group_desc_count; i++) {
458048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		fprintf(out, " Group %2d: block bitmap at %llu, "
459048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		        "inode bitmap at %llu, "
460048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		        "inode table at %llu\n"
4612418dfd7b934ee6bf3dc9a0aa4ffee8b37f4384fTheodore Ts'o		        "           %u free %s%s, "
462048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		        "%u free %s, "
463048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		        "%u used %s%s",
464048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		        i, ext2fs_block_bitmap_loc(current_fs, i),
465048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		        ext2fs_inode_bitmap_loc(current_fs, i),
466048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			ext2fs_inode_table_loc(current_fs, i),
4672418dfd7b934ee6bf3dc9a0aa4ffee8b37f4384fTheodore Ts'o		        ext2fs_bg_free_blocks_count(current_fs, i), units,
468048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		        ext2fs_bg_free_blocks_count(current_fs, i) != 1 ?
4692418dfd7b934ee6bf3dc9a0aa4ffee8b37f4384fTheodore Ts'o			"s" : "",
470048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		        ext2fs_bg_free_inodes_count(current_fs, i),
471048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		        ext2fs_bg_free_inodes_count(current_fs, i) != 1 ?
472048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			"inodes" : "inode",
473048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		        ext2fs_bg_used_dirs_count(current_fs, i),
474048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		        ext2fs_bg_used_dirs_count(current_fs, i) != 1 ? "directories"
475048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson 				: "directory", gdt_csum ? ", " : "\n");
4768fdf29117f922419bd5b3f741e5d554b1d5b8893Jose R. Santos		if (gdt_csum)
477048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			fprintf(out, "%u unused %s\n",
478048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson				ext2fs_bg_itable_unused(current_fs, i),
479048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson				ext2fs_bg_itable_unused(current_fs, i) != 1 ?
480048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson				"inodes" : "inode");
481f5fa20078bfc05b554294fe9c5505375d7913e8cTheodore Ts'o		first = 1;
482732c8cd58ff30ffae0d3276c411a08920717a46cTheodore Ts'o		print_bg_opts(current_fs, i, EXT2_BG_INODE_UNINIT, "Inode not init",
483f5fa20078bfc05b554294fe9c5505375d7913e8cTheodore Ts'o			      &first, out);
484732c8cd58ff30ffae0d3276c411a08920717a46cTheodore Ts'o		print_bg_opts(current_fs, i, EXT2_BG_BLOCK_UNINIT, "Block not init",
485f5fa20078bfc05b554294fe9c5505375d7913e8cTheodore Ts'o			      &first, out);
4868fdf29117f922419bd5b3f741e5d554b1d5b8893Jose R. Santos		if (gdt_csum) {
4878fdf29117f922419bd5b3f741e5d554b1d5b8893Jose R. Santos			fprintf(out, "%sChecksum 0x%04x",
488048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson				first ? "           [":", ", ext2fs_bg_checksum(current_fs, i));
4898fdf29117f922419bd5b3f741e5d554b1d5b8893Jose R. Santos			first = 0;
4908fdf29117f922419bd5b3f741e5d554b1d5b8893Jose R. Santos		}
491f5fa20078bfc05b554294fe9c5505375d7913e8cTheodore Ts'o		if (!first)
492f5fa20078bfc05b554294fe9c5505375d7913e8cTheodore Ts'o			fputs("]\n", out);
493f5fa20078bfc05b554294fe9c5505375d7913e8cTheodore Ts'o	}
4943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	close_pager(out);
4959b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o	return;
4969b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'oprint_usage:
4979b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o	fprintf(stderr, "%s: Usage: show_super [-h]\n", argv[0]);
4983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
4993839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
500e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#ifndef READ_ONLY
501efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ovoid do_dirty_filesys(int argc EXT2FS_ATTR((unused)),
502544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		      char **argv EXT2FS_ATTR((unused)))
50321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o{
50421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	if (check_fs_open(argv[0]))
50521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		return;
506601002bd2a144da02165529743a4b1621cfe9ae3Theodore Ts'o	if (check_fs_read_write(argv[0]))
507601002bd2a144da02165529743a4b1621cfe9ae3Theodore Ts'o		return;
508601002bd2a144da02165529743a4b1621cfe9ae3Theodore Ts'o
509601002bd2a144da02165529743a4b1621cfe9ae3Theodore Ts'o	if (argv[1] && !strcmp(argv[1], "-clean"))
510601002bd2a144da02165529743a4b1621cfe9ae3Theodore Ts'o		current_fs->super->s_state |= EXT2_VALID_FS;
511601002bd2a144da02165529743a4b1621cfe9ae3Theodore Ts'o	else
512601002bd2a144da02165529743a4b1621cfe9ae3Theodore Ts'o		current_fs->super->s_state &= ~EXT2_VALID_FS;
51321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	ext2fs_mark_super_dirty(current_fs);
51421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o}
515e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#endif /* READ_ONLY */
51621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o
5173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostruct list_blocks_struct {
51889e25cfdbf206d6840dc92385ee839dd850294dbAndreas Dilger	FILE		*f;
51989e25cfdbf206d6840dc92385ee839dd850294dbAndreas Dilger	e2_blkcnt_t	total;
520048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	blk64_t		first_block, last_block;
52189e25cfdbf206d6840dc92385ee839dd850294dbAndreas Dilger	e2_blkcnt_t	first_bcnt, last_bcnt;
52289e25cfdbf206d6840dc92385ee839dd850294dbAndreas Dilger	e2_blkcnt_t	first;
5233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o};
5243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
5250a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'ostatic void finish_range(struct list_blocks_struct *lb)
5260a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o{
5270a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o	if (lb->first_block == 0)
5280a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o		return;
5290a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o	if (lb->first)
5300a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o		lb->first = 0;
5310a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o	else
53280bfaa3e40ae6ab00cc3d4d1f4c0eeefce0b1a96Theodore Ts'o		fprintf(lb->f, ", ");
5330a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o	if (lb->first_block == lb->last_block)
534048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		fprintf(lb->f, "(%lld):%llu",
535de8f3a76218255e443ba57dec5d74850180fa75dAndreas Dilger			(long long)lb->first_bcnt, lb->first_block);
5360a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o	else
537048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		fprintf(lb->f, "(%lld-%lld):%llu-%llu",
538de8f3a76218255e443ba57dec5d74850180fa75dAndreas Dilger			(long long)lb->first_bcnt, (long long)lb->last_bcnt,
539de8f3a76218255e443ba57dec5d74850180fa75dAndreas Dilger			lb->first_block, lb->last_block);
5400a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o	lb->first_block = 0;
5410a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o}
5420a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o
543efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ostatic int list_blocks_proc(ext2_filsys fs EXT2FS_ATTR((unused)),
544048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			    blk64_t *blocknr, e2_blkcnt_t blockcnt,
545048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			    blk64_t ref_block EXT2FS_ATTR((unused)),
546efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o			    int ref_offset EXT2FS_ATTR((unused)),
547544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o			    void *private)
5483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
5493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	struct list_blocks_struct *lb = (struct list_blocks_struct *) private;
5503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
5510a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o	lb->total++;
5520a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o	if (blockcnt >= 0) {
5530a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o		/*
5540a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o		 * See if we can add on to the existing range (if it exists)
5550a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o		 */
5560a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o		if (lb->first_block &&
5570a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o		    (lb->last_block+1 == *blocknr) &&
5580a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o		    (lb->last_bcnt+1 == blockcnt)) {
5590a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o			lb->last_block = *blocknr;
5600a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o			lb->last_bcnt = blockcnt;
5610a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o			return 0;
5620a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o		}
5630a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o		/*
5640a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o		 * Start a new range.
5650a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o		 */
5660a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o		finish_range(lb);
5670a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o		lb->first_block = lb->last_block = *blocknr;
5680a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o		lb->first_bcnt = lb->last_bcnt = blockcnt;
5690a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o		return 0;
5700a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o	}
5710a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o	/*
5720a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o	 * Not a normal block.  Always force a new range.
5730a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o	 */
5740a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o	finish_range(lb);
5750a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o	if (lb->first)
5760a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o		lb->first = 0;
5770a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o	else
5782c4a540636142a936889bbe4b85a2b9c56bfa458Theodore Ts'o		fprintf(lb->f, ", ");
579a5eef73b6419e19bc8b66ed476fcf516952a4c67Theodore Ts'o	if (blockcnt == -1)
580048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		fprintf(lb->f, "(IND):%llu", (unsigned long long) *blocknr);
581a5eef73b6419e19bc8b66ed476fcf516952a4c67Theodore Ts'o	else if (blockcnt == -2)
582048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		fprintf(lb->f, "(DIND):%llu", (unsigned long long) *blocknr);
583a5eef73b6419e19bc8b66ed476fcf516952a4c67Theodore Ts'o	else if (blockcnt == -3)
584048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		fprintf(lb->f, "(TIND):%llu", (unsigned long long) *blocknr);
5853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
5863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
5873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
588efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ostatic void internal_dump_inode_extra(FILE *out,
589de8f3a76218255e443ba57dec5d74850180fa75dAndreas Dilger				      const char *prefix EXT2FS_ATTR((unused)),
590efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o				      ext2_ino_t inode_num EXT2FS_ATTR((unused)),
5919b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o				      struct ext2_inode_large *inode)
592ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o{
5938deb80a5d1078cbe43eaffcdeebf0a1a549d6a54Takashi Sato	fprintf(out, "Size of extra inode fields: %u\n", inode->i_extra_isize);
594ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o	if (inode->i_extra_isize > EXT2_INODE_SIZE(current_fs->super) -
595ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o			EXT2_GOOD_OLD_INODE_SIZE) {
596ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o		fprintf(stderr, "invalid inode->i_extra_isize (%u)\n",
597ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o				inode->i_extra_isize);
598ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o		return;
599ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o	}
6005beff1c0cfaf59a80bbd86a4b1436b39133b2abfDarrick J. Wong}
6015beff1c0cfaf59a80bbd86a4b1436b39133b2abfDarrick J. Wong
6025e4f070952bb4472e28a925f591b551baf2db278Theodore Ts'ostatic void dump_blocks(FILE *f, const char *prefix, ext2_ino_t inode)
6033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
6043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	struct list_blocks_struct lb;
6053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
606da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	fprintf(f, "%sBLOCKS:\n%s", prefix, prefix);
6073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	lb.total = 0;
6080a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o	lb.first_block = 0;
6093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	lb.f = f;
6100a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o	lb.first = 1;
611048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	ext2fs_block_iterate3(current_fs, inode, BLOCK_FLAG_READ_ONLY, NULL,
612048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			      list_blocks_proc, (void *)&lb);
6130a3db93a1c6e76086553b27192612f8616df4c4cTheodore Ts'o	finish_range(&lb);
6143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (lb.total)
615de8f3a76218255e443ba57dec5d74850180fa75dAndreas Dilger		fprintf(f, "\n%sTOTAL: %lld\n", prefix, (long long)lb.total);
6163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	fprintf(f,"\n");
6173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
6183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
619187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'ostatic int int_log10(unsigned long long arg)
620187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o{
621187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	int     l = 0;
622187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
623187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	arg = arg / 10;
624187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	while (arg) {
625187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		l++;
626187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		arg = arg / 10;
627187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	}
628187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	return l;
629187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o}
630187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
631187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o#define DUMP_LEAF_EXTENTS	0x01
632187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o#define DUMP_NODE_EXTENTS	0x02
633187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o#define DUMP_EXTENT_TABLE	0x04
634187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
635187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'ostatic void dump_extents(FILE *f, const char *prefix, ext2_ino_t ino,
636187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			 int flags, int logical_width, int physical_width)
637187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o{
638187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	ext2_extent_handle_t	handle;
639187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	struct ext2fs_extent	extent;
640187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	struct ext2_extent_info info;
641187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	int			op = EXT2_EXTENT_ROOT;
642187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	unsigned int		printed = 0;
643187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	errcode_t 		errcode;
644187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
645187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	errcode = ext2fs_extent_open(current_fs, ino, &handle);
646187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	if (errcode)
647187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		return;
648187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
649187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	if (flags & DUMP_EXTENT_TABLE)
650187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		fprintf(f, "Level Entries %*s %*s Length Flags\n",
651187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			(logical_width*2)+3, "Logical",
652187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			(physical_width*2)+3, "Physical");
653187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	else
654187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		fprintf(f, "%sEXTENTS:\n%s", prefix, prefix);
655187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
656187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	while (1) {
657187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		errcode = ext2fs_extent_get(handle, op, &extent);
658187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
659187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		if (errcode)
660187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			break;
661187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
662187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		op = EXT2_EXTENT_NEXT;
663187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
664187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		if (extent.e_flags & EXT2_EXTENT_FLAGS_SECOND_VISIT)
665187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			continue;
666187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
667187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		if (extent.e_flags & EXT2_EXTENT_FLAGS_LEAF) {
668187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			if ((flags & DUMP_LEAF_EXTENTS) == 0)
669187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				continue;
670187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		} else {
671187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			if ((flags & DUMP_NODE_EXTENTS) == 0)
672187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				continue;
673187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		}
674187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
675187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		errcode = ext2fs_extent_get_info(handle, &info);
676187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		if (errcode)
677187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			continue;
678187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
679187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		if (!(extent.e_flags & EXT2_EXTENT_FLAGS_LEAF)) {
680187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			if (extent.e_flags & EXT2_EXTENT_FLAGS_SECOND_VISIT)
681187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				continue;
682187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
683187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			if (flags & DUMP_EXTENT_TABLE) {
684187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				fprintf(f, "%2d/%2d %3d/%3d %*llu - %*llu "
685187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o					"%*llu%*s %6u\n",
686187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o					info.curr_level, info.max_depth,
687187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o					info.curr_entry, info.num_entries,
688187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o					logical_width,
689187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o					extent.e_lblk,
690187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o					logical_width,
691187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o					extent.e_lblk + (extent.e_len - 1),
692187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o					physical_width,
693187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o					extent.e_pblk,
694187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o					physical_width+3, "", extent.e_len);
695187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				continue;
696187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			}
697187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
698a9468442350b4c1e6e029493bfbc1a840b1f7efeTheodore Ts'o			fprintf(f, "%s(ETB%d):%lld",
699c4b87b8c4ff6f3efff86f96dbef3ed050a712354Theodore Ts'o				printed ? ", " : "", info.curr_level,
700187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				extent.e_pblk);
701187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			printed = 1;
702187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			continue;
703187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		}
704187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
705187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		if (flags & DUMP_EXTENT_TABLE) {
706187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			fprintf(f, "%2d/%2d %3d/%3d %*llu - %*llu "
707187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				"%*llu - %*llu %6u %s\n",
708187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				info.curr_level, info.max_depth,
709187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				info.curr_entry, info.num_entries,
710187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				logical_width,
711187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				extent.e_lblk,
712187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				logical_width,
713187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				extent.e_lblk + (extent.e_len - 1),
714187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				physical_width,
715187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				extent.e_pblk,
716187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				physical_width,
717187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				extent.e_pblk + (extent.e_len - 1),
718187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				extent.e_len,
719187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT ?
720187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o					"Uninit" : "");
721187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			continue;
722187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		}
723187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
724187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		if (extent.e_len == 0)
725187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			continue;
726187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		else if (extent.e_len == 1)
727187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			fprintf(f,
728a9468442350b4c1e6e029493bfbc1a840b1f7efeTheodore Ts'o				"%s(%lld%s):%lld",
729187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				printed ? ", " : "",
730187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				extent.e_lblk,
731187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT ?
732a9468442350b4c1e6e029493bfbc1a840b1f7efeTheodore Ts'o				"[u]" : "",
733187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				extent.e_pblk);
734187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		else
735187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			fprintf(f,
736a9468442350b4c1e6e029493bfbc1a840b1f7efeTheodore Ts'o				"%s(%lld-%lld%s):%lld-%lld",
737187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				printed ? ", " : "",
738187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				extent.e_lblk,
739187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				extent.e_lblk + (extent.e_len - 1),
740187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT ?
741a9468442350b4c1e6e029493bfbc1a840b1f7efeTheodore Ts'o					"[u]" : "",
742187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				extent.e_pblk,
743187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				extent.e_pblk + (extent.e_len - 1));
744187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		printed = 1;
745187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	}
746187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	if (printed)
747187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		fprintf(f, "\n");
7488a6cc1aebd7e9b2e6d6624fa1f8539888da25fe4Darrick J. Wong	ext2fs_extent_free(handle);
749187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o}
7503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
751133e94627b01823d2555450ddd1d95401ff2227aZheng Liustatic void dump_inline_data(FILE *out, const char *prefix, ext2_ino_t inode_num)
752133e94627b01823d2555450ddd1d95401ff2227aZheng Liu{
753133e94627b01823d2555450ddd1d95401ff2227aZheng Liu	errcode_t retval;
754133e94627b01823d2555450ddd1d95401ff2227aZheng Liu	size_t size;
755133e94627b01823d2555450ddd1d95401ff2227aZheng Liu
756133e94627b01823d2555450ddd1d95401ff2227aZheng Liu	retval = ext2fs_inline_data_size(current_fs, inode_num, &size);
757133e94627b01823d2555450ddd1d95401ff2227aZheng Liu	if (!retval)
7587ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong		fprintf(out, "%sSize of inline data: %zu\n", prefix, size);
7597ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong}
7607ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong
7617ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wongstatic void dump_fast_link(FILE *out, ext2_ino_t inode_num,
7627ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong			   struct ext2_inode *inode, const char *prefix)
7637ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong{
7647ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong	errcode_t retval = 0;
7657ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong	char *buf;
7667ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong	size_t size;
7677ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong
7687ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong	if (inode->i_flags & EXT4_INLINE_DATA_FL) {
7697ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong		retval = ext2fs_inline_data_size(current_fs, inode_num, &size);
7707ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong		if (retval)
7717ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong			goto out;
7727ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong
7737ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong		retval = ext2fs_get_memzero(size + 1, &buf);
7747ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong		if (retval)
7757ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong			goto out;
7767ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong
7777ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong		retval = ext2fs_inline_data_get(current_fs, inode_num,
7787ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong						inode, buf, &size);
7797ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong		if (retval)
7807ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong			goto out;
7817ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong		fprintf(out, "%sFast link dest: \"%.*s\"\n", prefix,
7827ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong			(int)size, buf);
7837ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong
7847ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong		retval = ext2fs_free_mem(&buf);
7857ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong		if (retval)
7867ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong			goto out;
7877ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong	} else {
788df0b907ec1625b058814f42119c9a736f2c34c96Theodore Ts'o		size_t sz = EXT2_I_SIZE(inode);
7897ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong
7907ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong		if (sz > sizeof(inode->i_block))
7917ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong			sz = sizeof(inode->i_block);
792df0b907ec1625b058814f42119c9a736f2c34c96Theodore Ts'o		fprintf(out, "%sFast link dest: \"%.*s\"\n", prefix, (int) sz,
7937ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong			(char *)inode->i_block);
7947ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong	}
7957ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wongout:
7967ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong	if (retval)
7977ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong		com_err(__func__, retval, "while dumping link destination");
798133e94627b01823d2555450ddd1d95401ff2227aZheng Liu}
799133e94627b01823d2555450ddd1d95401ff2227aZheng Liu
8005e4f070952bb4472e28a925f591b551baf2db278Theodore Ts'ovoid internal_dump_inode(FILE *out, const char *prefix,
801da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			 ext2_ino_t inode_num, struct ext2_inode *inode,
802da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			 int do_dump_blocks)
8033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
80450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	const char *i_type;
805fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	char frag, fsize;
806fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	int os = current_fs->super->s_creator_os;
807a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o	struct ext2_inode_large *large_inode;
808a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o	int is_large_inode = 0;
809a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o
810a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o	if (EXT2_INODE_SIZE(current_fs->super) > EXT2_GOOD_OLD_INODE_SIZE)
811a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o		is_large_inode = 1;
812a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o	large_inode = (struct ext2_inode_large *) inode;
813a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o
814da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (LINUX_S_ISDIR(inode->i_mode)) i_type = "directory";
815da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	else if (LINUX_S_ISREG(inode->i_mode)) i_type = "regular";
816da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	else if (LINUX_S_ISLNK(inode->i_mode)) i_type = "symlink";
817da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	else if (LINUX_S_ISBLK(inode->i_mode)) i_type = "block special";
818da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	else if (LINUX_S_ISCHR(inode->i_mode)) i_type = "character special";
819da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	else if (LINUX_S_ISFIFO(inode->i_mode)) i_type = "FIFO";
820da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	else if (LINUX_S_ISSOCK(inode->i_mode)) i_type = "socket";
8213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else i_type = "bad type";
822da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	fprintf(out, "%sInode: %u   Type: %s    ", prefix, inode_num, i_type);
823a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o	fprintf(out, "%sMode:  %04o   Flags: 0x%x\n",
824a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o		prefix, inode->i_mode & 0777, inode->i_flags);
825a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o	if (is_large_inode && large_inode->i_extra_isize >= 24) {
826efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		fprintf(out, "%sGeneration: %u    Version: 0x%08x:%08x\n",
827a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o			prefix, inode->i_generation, large_inode->i_version_hi,
828a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o			inode->osd1.linux1.l_i_version);
829a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o	} else {
830efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		fprintf(out, "%sGeneration: %u    Version: 0x%08x\n", prefix,
831a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o			inode->i_generation, inode->osd1.linux1.l_i_version);
832a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o	}
833f3d9ac36a021aab3d84ef7759790839f9a65a1bfTheodore Ts'o	fprintf(out, "%sUser: %5d   Group: %5d",
8345113a6e32b298671c86ae7da097bcd24540cebc9Eric Sandeen		prefix, inode_uid(*inode), inode_gid(*inode));
835f3d9ac36a021aab3d84ef7759790839f9a65a1bfTheodore Ts'o	if (is_large_inode && large_inode->i_extra_isize >= 32)
836f3d9ac36a021aab3d84ef7759790839f9a65a1bfTheodore Ts'o		fprintf(out, "   Project: %5d", large_inode->i_projid);
837f3d9ac36a021aab3d84ef7759790839f9a65a1bfTheodore Ts'o	fputs("   Size: ", out);
8380bd0e5932046401049502ee99529b984d7cd316eAndreas Dilger	if (LINUX_S_ISREG(inode->i_mode))
8390bd0e5932046401049502ee99529b984d7cd316eAndreas Dilger		fprintf(out, "%llu\n", EXT2_I_SIZE(inode));
8400bd0e5932046401049502ee99529b984d7cd316eAndreas Dilger	else
8411a6bb6274fc0a0fff9072dd63b39e716cb94d4edAndreas Dilger		fprintf(out, "%d\n", inode->i_size);
8425d17119d14fe1276936c85d7986695a4543b1aa1Theodore Ts'o	if (os == EXT2_OS_HURD)
84362c06f790c4920ec2721515e36d599751f6d4d2dTheodore Ts'o		fprintf(out,
844da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			"%sFile ACL: %d    Directory ACL: %d Translator: %d\n",
845da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			prefix,
846da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			inode->i_file_acl, LINUX_S_ISDIR(inode->i_mode) ? inode->i_dir_acl : 0,
847da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			inode->osd1.hurd1.h_i_translator);
84862c06f790c4920ec2721515e36d599751f6d4d2dTheodore Ts'o	else
84981624c3c7b4784f6651e807994db4792a49112ebTheodore Ts'o		fprintf(out, "%sFile ACL: %llu    Directory ACL: %d\n",
850da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			prefix,
85181624c3c7b4784f6651e807994db4792a49112ebTheodore Ts'o			inode->i_file_acl | ((long long)
85281624c3c7b4784f6651e807994db4792a49112ebTheodore Ts'o				(inode->osd2.linux2.l_i_file_acl_high) << 32),
85381624c3c7b4784f6651e807994db4792a49112ebTheodore Ts'o			LINUX_S_ISDIR(inode->i_mode) ? inode->i_dir_acl : 0);
854c0495d96fd1f7015e7beb3d9363cbe949d133173Theodore Ts'o	if (os != EXT2_OS_HURD)
8555d17119d14fe1276936c85d7986695a4543b1aa1Theodore Ts'o		fprintf(out, "%sLinks: %d   Blockcount: %llu\n",
856efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o			prefix, inode->i_links_count,
857efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o			(((unsigned long long)
858efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o			  inode->osd2.linux2.l_i_blocks_hi << 32)) +
8595d17119d14fe1276936c85d7986695a4543b1aa1Theodore Ts'o			inode->i_blocks);
8605d17119d14fe1276936c85d7986695a4543b1aa1Theodore Ts'o	else
8615d17119d14fe1276936c85d7986695a4543b1aa1Theodore Ts'o		fprintf(out, "%sLinks: %d   Blockcount: %u\n",
8625d17119d14fe1276936c85d7986695a4543b1aa1Theodore Ts'o			prefix, inode->i_links_count, inode->i_blocks);
863fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	switch (os) {
864fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	    case EXT2_OS_HURD:
865da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		frag = inode->osd2.hurd2.h_i_frag;
866da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		fsize = inode->osd2.hurd2.h_i_fsize;
867fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		break;
868fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	    default:
869fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		frag = fsize = 0;
870fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	}
871da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	fprintf(out, "%sFragment:  Address: %d    Number: %d    Size: %d\n",
872da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		prefix, inode->i_faddr, frag, fsize);
873a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o	if (is_large_inode && large_inode->i_extra_isize >= 24) {
874efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		fprintf(out, "%s ctime: 0x%08x:%08x -- %s", prefix,
875a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o			inode->i_ctime, large_inode->i_ctime_extra,
876188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o			inode_time_to_string(inode->i_ctime,
877188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o					     large_inode->i_ctime_extra));
878efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		fprintf(out, "%s atime: 0x%08x:%08x -- %s", prefix,
879a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o			inode->i_atime, large_inode->i_atime_extra,
880188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o			inode_time_to_string(inode->i_atime,
881188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o					     large_inode->i_atime_extra));
882a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o		fprintf(out, "%s mtime: 0x%08x:%08x -- %s", prefix,
883a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o			inode->i_mtime, large_inode->i_mtime_extra,
884188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o			inode_time_to_string(inode->i_mtime,
885188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o					     large_inode->i_mtime_extra));
886a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o		fprintf(out, "%scrtime: 0x%08x:%08x -- %s", prefix,
887a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o			large_inode->i_crtime, large_inode->i_crtime_extra,
888188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o			inode_time_to_string(large_inode->i_crtime,
889188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o					     large_inode->i_crtime_extra));
890188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o		if (inode->i_dtime)
89122137497fa13c1e38fdae96f43eb827c0f46692bTheodore Ts'o			fprintf(out, "%s dtime: 0x%08x:(%08x) -- %s", prefix,
892188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o				large_inode->i_dtime, large_inode->i_ctime_extra,
893188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o				inode_time_to_string(inode->i_dtime,
894188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o						     large_inode->i_ctime_extra));
895a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o	} else {
896a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o		fprintf(out, "%sctime: 0x%08x -- %s", prefix, inode->i_ctime,
897188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o			time_to_string((__s32) inode->i_ctime));
898a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o		fprintf(out, "%satime: 0x%08x -- %s", prefix, inode->i_atime,
899188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o			time_to_string((__s32) inode->i_atime));
900a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o		fprintf(out, "%smtime: 0x%08x -- %s", prefix, inode->i_mtime,
901188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o			time_to_string((__s32) inode->i_mtime));
902188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o		if (inode->i_dtime)
903188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o			fprintf(out, "%sdtime: 0x%08x -- %s", prefix,
904188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o				inode->i_dtime,
905188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o				time_to_string((__s32) inode->i_dtime));
906a16031c639c1965c7a35eb9ac9b2d45798efe7e9Theodore Ts'o	}
907ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o	if (EXT2_INODE_SIZE(current_fs->super) > EXT2_GOOD_OLD_INODE_SIZE)
908ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o		internal_dump_inode_extra(out, prefix, inode_num,
909ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o					  (struct ext2_inode_large *) inode);
9105beff1c0cfaf59a80bbd86a4b1436b39133b2abfDarrick J. Wong	dump_inode_attributes(out, inode_num);
911c0495d96fd1f7015e7beb3d9363cbe949d133173Theodore Ts'o	if (ext2fs_has_feature_metadata_csum(current_fs->super)) {
9126d0af0c85d2298cbb3acc8cfd860beb932623d23Darrick J. Wong		__u32 crc = inode->i_checksum_lo;
9136d0af0c85d2298cbb3acc8cfd860beb932623d23Darrick J. Wong		if (is_large_inode &&
9146d0af0c85d2298cbb3acc8cfd860beb932623d23Darrick J. Wong		    large_inode->i_extra_isize >=
9156d0af0c85d2298cbb3acc8cfd860beb932623d23Darrick J. Wong				(offsetof(struct ext2_inode_large,
9166d0af0c85d2298cbb3acc8cfd860beb932623d23Darrick J. Wong					  i_checksum_hi) -
9176d0af0c85d2298cbb3acc8cfd860beb932623d23Darrick J. Wong				 EXT2_GOOD_OLD_INODE_SIZE))
9186d0af0c85d2298cbb3acc8cfd860beb932623d23Darrick J. Wong			crc |= ((__u32)large_inode->i_checksum_hi) << 16;
9196d0af0c85d2298cbb3acc8cfd860beb932623d23Darrick J. Wong		fprintf(out, "Inode checksum: 0x%08x\n", crc);
9206d0af0c85d2298cbb3acc8cfd860beb932623d23Darrick J. Wong	}
9216d0af0c85d2298cbb3acc8cfd860beb932623d23Darrick J. Wong
922328731738d88eb6c32c784e7aa7871e576e9e8a5Zheng Liu	if (LINUX_S_ISLNK(inode->i_mode) &&
9237ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong	    ext2fs_inode_data_blocks(current_fs, inode) == 0)
9247ba5cc744b842da7a7109fbf8f0c53dbc63bcae1Darrick J. Wong		dump_fast_link(out, inode_num, inode, prefix);
9252d10769ec6745b1e4bab371764d65bb3587ab285Theodore Ts'o	else if (LINUX_S_ISBLK(inode->i_mode) || LINUX_S_ISCHR(inode->i_mode)) {
9262d10769ec6745b1e4bab371764d65bb3587ab285Theodore Ts'o		int major, minor;
9272d10769ec6745b1e4bab371764d65bb3587ab285Theodore Ts'o		const char *devnote;
9282d10769ec6745b1e4bab371764d65bb3587ab285Theodore Ts'o
9292d10769ec6745b1e4bab371764d65bb3587ab285Theodore Ts'o		if (inode->i_block[0]) {
9302d10769ec6745b1e4bab371764d65bb3587ab285Theodore Ts'o			major = (inode->i_block[0] >> 8) & 255;
9312d10769ec6745b1e4bab371764d65bb3587ab285Theodore Ts'o			minor = inode->i_block[0] & 255;
9322d10769ec6745b1e4bab371764d65bb3587ab285Theodore Ts'o			devnote = "";
9332d10769ec6745b1e4bab371764d65bb3587ab285Theodore Ts'o		} else {
9342d10769ec6745b1e4bab371764d65bb3587ab285Theodore Ts'o			major = (inode->i_block[1] & 0xfff00) >> 8;
935efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o			minor = ((inode->i_block[1] & 0xff) |
9362d10769ec6745b1e4bab371764d65bb3587ab285Theodore Ts'o				 ((inode->i_block[1] >> 12) & 0xfff00));
9372d10769ec6745b1e4bab371764d65bb3587ab285Theodore Ts'o			devnote = "(New-style) ";
9382d10769ec6745b1e4bab371764d65bb3587ab285Theodore Ts'o		}
939efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		fprintf(out, "%sDevice major/minor number: %02d:%02d (hex %02x:%02x)\n",
9402d10769ec6745b1e4bab371764d65bb3587ab285Theodore Ts'o			devnote, major, minor, major, minor);
941187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	} else if (do_dump_blocks) {
942187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		if (inode->i_flags & EXT4_EXTENTS_FL)
943187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			dump_extents(out, prefix, inode_num,
944c4b87b8c4ff6f3efff86f96dbef3ed050a712354Theodore Ts'o				     DUMP_LEAF_EXTENTS|DUMP_NODE_EXTENTS, 0, 0);
945133e94627b01823d2555450ddd1d95401ff2227aZheng Liu		else if (inode->i_flags & EXT4_INLINE_DATA_FL)
946133e94627b01823d2555450ddd1d95401ff2227aZheng Liu			dump_inline_data(out, prefix, inode_num);
947187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		else
948187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			dump_blocks(out, prefix, inode_num);
9492d10769ec6745b1e4bab371764d65bb3587ab285Theodore Ts'o	}
950da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o}
951da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
952ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'ostatic void dump_inode(ext2_ino_t inode_num, struct ext2_inode *inode)
953da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{
954da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	FILE	*out;
955efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
956da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	out = open_pager();
957ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o	internal_dump_inode(out, "", inode_num, inode, 1);
9583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	close_pager(out);
9593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
9603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
9613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_stat(int argc, char *argv[])
9623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
963b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	ext2_ino_t	inode;
964ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o	struct ext2_inode * inode_buf;
9653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
96664777391eb2bdc0d57319bb9895b840a4c60e475Theodore Ts'o	if (check_fs_open(argv[0]))
9678363e357b2cf943396ec7165e389a20385e40ab6Theodore Ts'o		return;
96864777391eb2bdc0d57319bb9895b840a4c60e475Theodore Ts'o
969ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o	inode_buf = (struct ext2_inode *)
970ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o			malloc(EXT2_INODE_SIZE(current_fs->super));
971ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o	if (!inode_buf) {
972ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o		fprintf(stderr, "do_stat: can't allocate buffer\n");
9733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
974ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o	}
9753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
976ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o	if (common_inode_args_process(argc, argv, &inode, 0)) {
977ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o		free(inode_buf);
978ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o		return;
979ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o	}
980ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o
981ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o	if (debugfs_read_inode_full(inode, inode_buf, argv[0],
982ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o					EXT2_INODE_SIZE(current_fs->super))) {
983ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o		free(inode_buf);
984e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		return;
985ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o	}
9863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
987ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o	dump_inode(inode, inode_buf);
988ea822eeba373bd0bed6e58a35ce123a9f2768113Theodore Ts'o	free(inode_buf);
9893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return;
9903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
9913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
992cf5301d7f2c3bbed3d26600335102414cbf0c4baAndreas Dilgervoid do_dump_extents(int argc, char **argv)
993187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o{
994187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	struct ext2_inode inode;
995187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	ext2_ino_t	ino;
996187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	FILE		*out;
997187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	int		c, flags = 0;
998187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	int		logical_width;
999187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	int		physical_width;
1000187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
1001187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	reset_getopt();
1002187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	while ((c = getopt(argc, argv, "nl")) != EOF) {
1003187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		switch (c) {
1004187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		case 'n':
1005187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			flags |= DUMP_NODE_EXTENTS;
1006187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			break;
1007187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		case 'l':
1008187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			flags |= DUMP_LEAF_EXTENTS;
1009187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			break;
1010187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		}
1011187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	}
1012187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
1013cf5301d7f2c3bbed3d26600335102414cbf0c4baAndreas Dilger	if (argc != optind + 1) {
1014187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		com_err(0, 0, "Usage: dump_extents [-n] [-l] file");
1015187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		return;
1016187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	}
1017187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
1018187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	if (flags == 0)
1019187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		flags = DUMP_NODE_EXTENTS | DUMP_LEAF_EXTENTS;
1020187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	flags |= DUMP_EXTENT_TABLE;
1021187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
1022187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	if (check_fs_open(argv[0]))
1023187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		return;
1024187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
1025187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	ino = string_to_inode(argv[optind]);
1026187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	if (ino == 0)
1027187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		return;
1028187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
1029187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	if (debugfs_read_inode(ino, &inode, argv[0]))
1030187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		return;
1031187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
1032187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	if ((inode.i_flags & EXT4_EXTENTS_FL) == 0) {
1033187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		fprintf(stderr, "%s: does not uses extent block maps\n",
1034187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o			argv[optind]);
1035187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		return;
1036187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	}
1037187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
10380bd0e5932046401049502ee99529b984d7cd316eAndreas Dilger	logical_width = int_log10((EXT2_I_SIZE(&inode)+current_fs->blocksize-1)/
1039187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o				  current_fs->blocksize) + 1;
1040187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	if (logical_width < 5)
1041187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		logical_width = 5;
10424efbac6fed75c29d3d5f1b676b932754653a2ac5Valerie Aurora Henson	physical_width = int_log10(ext2fs_blocks_count(current_fs->super)) + 1;
1043187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	if (physical_width < 5)
1044187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o		physical_width = 5;
1045187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
1046187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	out = open_pager();
1047187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	dump_extents(out, "", ino, flags, logical_width, physical_width);
1048187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	close_pager(out);
1049187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o	return;
1050187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o}
1051187cb623dc8085439d366dceb07bc2191da3c21eTheodore Ts'o
1052af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'ostatic int print_blocks_proc(ext2_filsys fs EXT2FS_ATTR((unused)),
1053af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o			     blk64_t *blocknr,
10543cebf9c1029ca983ebbbae79f7905a02d087ff98Theodore Ts'o			     e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
1055af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o			     blk64_t ref_block EXT2FS_ATTR((unused)),
1056af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o			     int ref_offset EXT2FS_ATTR((unused)),
1057af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o			     void *private EXT2FS_ATTR((unused)))
1058af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o{
1059af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o	printf("%llu ", *blocknr);
1060af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o	return 0;
1061af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o}
1062af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o
1063af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'ovoid do_blocks(int argc, char *argv[])
1064af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o{
1065af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o	ext2_ino_t	inode;
1066af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o
1067af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o	if (check_fs_open(argv[0]))
1068af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o		return;
1069af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o
1070af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o	if (common_inode_args_process(argc, argv, &inode, 0)) {
1071af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o		return;
1072af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o	}
1073af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o
1074af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o	ext2fs_block_iterate3(current_fs, inode, BLOCK_FLAG_READ_ONLY, NULL,
1075af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o			      print_blocks_proc, NULL);
1076af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o	fputc('\n', stdout);
1077af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o	return;
1078af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o}
1079af0df2aa4a073f7e1a2d58b40010ecd891e80a60Theodore Ts'o
10803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_chroot(int argc, char *argv[])
10813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1082b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	ext2_ino_t inode;
10833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int retval;
10843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1085e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (common_inode_args_process(argc, argv, &inode, 0))
10863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
10873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1088fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	retval = ext2fs_check_directory(current_fs, inode);
10893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (retval)  {
10909b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o		com_err(argv[1], retval, 0);
10913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
10923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
10933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	root = inode;
10943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
10953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1096e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#ifndef READ_ONLY
10973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_clri(int argc, char *argv[])
10983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1099b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	ext2_ino_t inode;
11003839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	struct ext2_inode inode_buf;
11013839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1102e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (common_inode_args_process(argc, argv, &inode, CHECK_FS_RW))
11033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
11043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1105e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (debugfs_read_inode(inode, &inode_buf, argv[0]))
11063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
11073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	memset(&inode_buf, 0, sizeof(inode_buf));
1108e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (debugfs_write_inode(inode, &inode_buf, argv[0]))
11093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
11103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
11113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
11123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_freei(int argc, char *argv[])
11133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
11142ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	unsigned int	len = 1;
11152ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	int		err = 0;
11162ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	ext2_ino_t	inode;
11172ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o
11182ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	if (common_args_process(argc, argv, 2, 3, argv[0], "<file> [num]",
11192ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o				CHECK_FS_RW | CHECK_FS_BITMAPS))
1120e64e6761aa22f31123a91206a5686526f7b9c6c0Theodore Ts'o		return;
11212ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	if (check_fs_read_write(argv[0]))
11222ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o		return;
11233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
11242ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	inode = string_to_inode(argv[1]);
11252ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	if (!inode)
11263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
11273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
11282ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	if (argc == 3) {
11292ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o		len = parse_ulong(argv[2], argv[0], "length", &err);
11302ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o		if (err)
11312ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o			return;
11322ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	}
11332ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o
11342ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	if (len == 1 &&
11352ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	    !ext2fs_test_inode_bitmap2(current_fs->inode_map,inode))
11363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		com_err(argv[0], 0, "Warning: inode already clear");
11372ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	while (len-- > 0)
1138a9b23fc99da8c8918cb5fb8dcd1732edb70ad382Lev Solomonov		ext2fs_unmark_inode_bitmap2(current_fs->inode_map, inode++);
1139fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	ext2fs_mark_ib_dirty(current_fs);
11403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
11413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
11423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_seti(int argc, char *argv[])
11433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
11442ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	unsigned int	len = 1;
11452ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	int		err = 0;
11462ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	ext2_ino_t	inode;
11473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
11482ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	if (common_args_process(argc, argv, 2, 3, argv[0], "<file> [num]",
11492ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o				CHECK_FS_RW | CHECK_FS_BITMAPS))
11502ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o		return;
11512ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	if (check_fs_read_write(argv[0]))
11523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
11533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
11542ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	inode = string_to_inode(argv[1]);
11552ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	if (!inode)
11562ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o		return;
11572ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o
11582ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	if (argc == 3) {
11592ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o		len = parse_ulong(argv[2], argv[0], "length", &err);
11602ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o		if (err)
11612ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o			return;
11622ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	}
11632ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o
11642ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	if ((len == 1) &&
11652ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	    ext2fs_test_inode_bitmap2(current_fs->inode_map,inode))
11663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		com_err(argv[0], 0, "Warning: inode already set");
11672ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o	while (len-- > 0)
11682ae5d1fdb82b31bf270c4699c59a087c846db2f0Theodore Ts'o		ext2fs_mark_inode_bitmap2(current_fs->inode_map, inode++);
1169fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	ext2fs_mark_ib_dirty(current_fs);
11703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
1171e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#endif /* READ_ONLY */
11723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
11733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_testi(int argc, char *argv[])
11743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1175b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	ext2_ino_t inode;
11763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1177e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (common_inode_args_process(argc, argv, &inode, CHECK_FS_BITMAPS))
11783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
11793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
11806d879a999bad95724304a2a5158d7da4fcd599e7Valerie Aurora Henson	if (ext2fs_test_inode_bitmap2(current_fs->inode_map,inode))
1181b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o		printf("Inode %u is marked in use\n", inode);
11823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else
1183b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o		printf("Inode %u is not in use\n", inode);
11843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
11853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1186e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#ifndef READ_ONLY
11873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_freeb(int argc, char *argv[])
11883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1189048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	blk64_t block;
1190048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	blk64_t count = 1;
11913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1192e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (common_block_args_process(argc, argv, &block, &count))
11933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
1194fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	if (check_fs_read_write(argv[0]))
11953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
1196e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	while (count-- > 0) {
11976d879a999bad95724304a2a5158d7da4fcd599e7Valerie Aurora Henson		if (!ext2fs_test_block_bitmap2(current_fs->block_map,block))
1198048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			com_err(argv[0], 0, "Warning: block %llu already clear",
1199e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o				block);
12006d879a999bad95724304a2a5158d7da4fcd599e7Valerie Aurora Henson		ext2fs_unmark_block_bitmap2(current_fs->block_map,block);
1201e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		block++;
1202e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	}
1203fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	ext2fs_mark_bb_dirty(current_fs);
12043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
12053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
12063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_setb(int argc, char *argv[])
12073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1208048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	blk64_t block;
1209048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	blk64_t count = 1;
12103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1211e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (common_block_args_process(argc, argv, &block, &count))
12123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
1213fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	if (check_fs_read_write(argv[0]))
12143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
1215e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	while (count-- > 0) {
12166d879a999bad95724304a2a5158d7da4fcd599e7Valerie Aurora Henson		if (ext2fs_test_block_bitmap2(current_fs->block_map,block))
1217048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			com_err(argv[0], 0, "Warning: block %llu already set",
1218e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o				block);
12196d879a999bad95724304a2a5158d7da4fcd599e7Valerie Aurora Henson		ext2fs_mark_block_bitmap2(current_fs->block_map,block);
1220e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		block++;
1221e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	}
1222fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	ext2fs_mark_bb_dirty(current_fs);
12233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
1224e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#endif /* READ_ONLY */
12253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
12263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_testb(int argc, char *argv[])
12273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1228048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	blk64_t block;
1229048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	blk64_t count = 1;
12303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1231e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (common_block_args_process(argc, argv, &block, &count))
12323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
1233e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	while (count-- > 0) {
12346d879a999bad95724304a2a5158d7da4fcd599e7Valerie Aurora Henson		if (ext2fs_test_block_bitmap2(current_fs->block_map,block))
1235048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			printf("Block %llu marked in use\n", block);
1236e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		else
1237048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			printf("Block %llu not in use\n", block);
1238e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		block++;
12393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
12403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
12413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1242e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#ifndef READ_ONLY
124350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'ostatic void modify_u8(char *com, const char *prompt,
124450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		      const char *format, __u8 *val)
12453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
12463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	char buf[200];
124721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	unsigned long v;
12483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	char *tmp;
12493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
12503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	sprintf(buf, format, *val);
12513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	printf("%30s    [%s] ", prompt, buf);
1252d9039ae0ff3f7929ede576058b3ad3e9c62a47c4Dmitry V. Levin	if (!fgets(buf, sizeof(buf), stdin))
1253d9039ae0ff3f7929ede576058b3ad3e9c62a47c4Dmitry V. Levin		return;
12543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (buf[strlen (buf) - 1] == '\n')
12553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		buf[strlen (buf) - 1] = '\0';
12563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (!buf[0])
12573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
125821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	v = strtoul(buf, &tmp, 0);
12593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (*tmp)
12603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		com_err(com, 0, "Bad value - %s", buf);
12613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else
12623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		*val = v;
12633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
12643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
126550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'ostatic void modify_u16(char *com, const char *prompt,
126650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		       const char *format, __u16 *val)
12673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
12683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	char buf[200];
126921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	unsigned long v;
12703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	char *tmp;
12713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
12723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	sprintf(buf, format, *val);
12733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	printf("%30s    [%s] ", prompt, buf);
1274d9039ae0ff3f7929ede576058b3ad3e9c62a47c4Dmitry V. Levin	if (!fgets(buf, sizeof(buf), stdin))
1275d9039ae0ff3f7929ede576058b3ad3e9c62a47c4Dmitry V. Levin		return;
12763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (buf[strlen (buf) - 1] == '\n')
12773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		buf[strlen (buf) - 1] = '\0';
12783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (!buf[0])
12793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
128021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	v = strtoul(buf, &tmp, 0);
12813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (*tmp)
12823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		com_err(com, 0, "Bad value - %s", buf);
12833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else
12843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		*val = v;
12853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
12863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
128750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'ostatic void modify_u32(char *com, const char *prompt,
128850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		       const char *format, __u32 *val)
12893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
12903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	char buf[200];
129121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	unsigned long v;
12923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	char *tmp;
12933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
12943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	sprintf(buf, format, *val);
12953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	printf("%30s    [%s] ", prompt, buf);
1296d9039ae0ff3f7929ede576058b3ad3e9c62a47c4Dmitry V. Levin	if (!fgets(buf, sizeof(buf), stdin))
1297d9039ae0ff3f7929ede576058b3ad3e9c62a47c4Dmitry V. Levin		return;
12983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (buf[strlen (buf) - 1] == '\n')
12993839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		buf[strlen (buf) - 1] = '\0';
13003839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (!buf[0])
13013839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
130221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	v = strtoul(buf, &tmp, 0);
13033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (*tmp)
13043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		com_err(com, 0, "Bad value - %s", buf);
13053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else
13063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		*val = v;
13073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
13083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
13093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
13103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_modify_inode(int argc, char *argv[])
13113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
13123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	struct ext2_inode inode;
1313b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	ext2_ino_t	inode_num;
1314b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	int 		i;
1315b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	unsigned char	*frag, *fsize;
1316b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	char		buf[80];
13177380ac903316c0fe91ed6706eb4d84249a9b348dTheodore Ts'o	int 		os;
1318b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	const char	*hex_format = "0x%x";
1319b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	const char	*octal_format = "0%o";
1320b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	const char	*decimal_format = "%d";
13218deb80a5d1078cbe43eaffcdeebf0a1a549d6a54Takashi Sato	const char	*unsignedlong_format = "%lu";
1322efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1323e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (common_inode_args_process(argc, argv, &inode_num, CHECK_FS_RW))
13243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
13253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
13267380ac903316c0fe91ed6706eb4d84249a9b348dTheodore Ts'o	os = current_fs->super->s_creator_os;
13277380ac903316c0fe91ed6706eb4d84249a9b348dTheodore Ts'o
1328e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (debugfs_read_inode(inode_num, &inode, argv[1]))
13293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
1330efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
133150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	modify_u16(argv[0], "Mode", octal_format, &inode.i_mode);
133250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	modify_u16(argv[0], "User ID", decimal_format, &inode.i_uid);
133350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	modify_u16(argv[0], "Group ID", decimal_format, &inode.i_gid);
13348deb80a5d1078cbe43eaffcdeebf0a1a549d6a54Takashi Sato	modify_u32(argv[0], "Size", unsignedlong_format, &inode.i_size);
133550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	modify_u32(argv[0], "Creation time", decimal_format, &inode.i_ctime);
133650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	modify_u32(argv[0], "Modification time", decimal_format, &inode.i_mtime);
133750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	modify_u32(argv[0], "Access time", decimal_format, &inode.i_atime);
133850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	modify_u32(argv[0], "Deletion time", decimal_format, &inode.i_dtime);
133950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	modify_u16(argv[0], "Link count", decimal_format, &inode.i_links_count);
13405d17119d14fe1276936c85d7986695a4543b1aa1Theodore Ts'o	if (os == EXT2_OS_LINUX)
1341efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		modify_u16(argv[0], "Block count high", unsignedlong_format,
13425d17119d14fe1276936c85d7986695a4543b1aa1Theodore Ts'o			   &inode.osd2.linux2.l_i_blocks_hi);
13438deb80a5d1078cbe43eaffcdeebf0a1a549d6a54Takashi Sato	modify_u32(argv[0], "Block count", unsignedlong_format, &inode.i_blocks);
134450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	modify_u32(argv[0], "File flags", hex_format, &inode.i_flags);
13453db9305a6bdb67f708c31400603a34e799af475fTheodore Ts'o	modify_u32(argv[0], "Generation", hex_format, &inode.i_generation);
134650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#if 0
134750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	modify_u32(argv[0], "Reserved1", decimal_format, &inode.i_reserved1);
134850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif
134950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	modify_u32(argv[0], "File acl", decimal_format, &inode.i_file_acl);
135036a43d675ef61d0f5d5b2ad62d2e670c408d14acTheodore Ts'o	if (LINUX_S_ISDIR(inode.i_mode))
135136a43d675ef61d0f5d5b2ad62d2e670c408d14acTheodore Ts'o		modify_u32(argv[0], "Directory acl", decimal_format, &inode.i_dir_acl);
135236a43d675ef61d0f5d5b2ad62d2e670c408d14acTheodore Ts'o	else
135336a43d675ef61d0f5d5b2ad62d2e670c408d14acTheodore Ts'o		modify_u32(argv[0], "High 32bits of size", decimal_format, &inode.i_size_high);
135462c06f790c4920ec2721515e36d599751f6d4d2dTheodore Ts'o
13555d17119d14fe1276936c85d7986695a4543b1aa1Theodore Ts'o	if (os == EXT2_OS_HURD)
135662c06f790c4920ec2721515e36d599751f6d4d2dTheodore Ts'o		modify_u32(argv[0], "Translator Block",
135762c06f790c4920ec2721515e36d599751f6d4d2dTheodore Ts'o			    decimal_format, &inode.osd1.hurd1.h_i_translator);
1358efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
135950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	modify_u32(argv[0], "Fragment address", decimal_format, &inode.i_faddr);
1360fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	switch (os) {
1361fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	    case EXT2_OS_HURD:
1362fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		frag = &inode.osd2.hurd2.h_i_frag;
1363fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		fsize = &inode.osd2.hurd2.h_i_fsize;
1364fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		break;
1365fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	    default:
1366fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		frag = fsize = 0;
1367fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	}
1368fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	if (frag)
1369fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		modify_u8(argv[0], "Fragment number", decimal_format, frag);
1370fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	if (fsize)
1371fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		modify_u8(argv[0], "Fragment size", decimal_format, fsize);
1372fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o
13733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	for (i=0;  i < EXT2_NDIR_BLOCKS; i++) {
13743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		sprintf(buf, "Direct Block #%d", i);
137550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		modify_u32(argv[0], buf, decimal_format, &inode.i_block[i]);
13763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
137750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	modify_u32(argv[0], "Indirect Block", decimal_format,
1378efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		    &inode.i_block[EXT2_IND_BLOCK]);
137950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	modify_u32(argv[0], "Double Indirect Block", decimal_format,
13803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		    &inode.i_block[EXT2_DIND_BLOCK]);
138150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	modify_u32(argv[0], "Triple Indirect Block", decimal_format,
13823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		    &inode.i_block[EXT2_TIND_BLOCK]);
1383e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (debugfs_write_inode(inode_num, &inode, argv[1]))
13843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
13853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
1386e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#endif /* READ_ONLY */
13873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
13883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_change_working_dir(int argc, char *argv[])
13893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1390b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	ext2_ino_t	inode;
1391b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	int		retval;
1392efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1393e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (common_inode_args_process(argc, argv, &inode, 0))
13943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
13953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1396fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	retval = ext2fs_check_directory(current_fs, inode);
13973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (retval) {
13989b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o		com_err(argv[1], retval, 0);
13993839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
14003839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
14013839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	cwd = inode;
14023839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return;
14033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
14043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
14053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_print_working_directory(int argc, char *argv[])
14063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
14073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int	retval;
14083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	char	*pathname = NULL;
1409efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1410e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (common_args_process(argc, argv, 1, 1,
1411e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o				"print_working_directory", "", 0))
14123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
14133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1414fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	retval = ext2fs_get_pathname(current_fs, cwd, 0, &pathname);
14153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (retval) {
14163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		com_err(argv[0], retval,
14173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			"while trying to get pathname of cwd");
14183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1419971fe056305c7f57629d609490701e13298e658bBrian Behlendorf	printf("[pwd]   INODE: %6u  PATH: %s\n",
1420971fe056305c7f57629d609490701e13298e658bBrian Behlendorf	       cwd, pathname ? pathname : "NULL");
1421971fe056305c7f57629d609490701e13298e658bBrian Behlendorf        if (pathname) {
1422971fe056305c7f57629d609490701e13298e658bBrian Behlendorf		free(pathname);
1423971fe056305c7f57629d609490701e13298e658bBrian Behlendorf		pathname = NULL;
1424971fe056305c7f57629d609490701e13298e658bBrian Behlendorf        }
1425fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	retval = ext2fs_get_pathname(current_fs, root, 0, &pathname);
14263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (retval) {
14273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		com_err(argv[0], retval,
14283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			"while trying to get pathname of root");
14293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1430971fe056305c7f57629d609490701e13298e658bBrian Behlendorf	printf("[root]  INODE: %6u  PATH: %s\n",
1431971fe056305c7f57629d609490701e13298e658bBrian Behlendorf	       root, pathname ? pathname : "NULL");
1432971fe056305c7f57629d609490701e13298e658bBrian Behlendorf	if (pathname) {
1433971fe056305c7f57629d609490701e13298e658bBrian Behlendorf		free(pathname);
1434971fe056305c7f57629d609490701e13298e658bBrian Behlendorf		pathname = NULL;
1435971fe056305c7f57629d609490701e13298e658bBrian Behlendorf	}
14363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return;
14373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
14383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
14393cebf9c1029ca983ebbbae79f7905a02d087ff98Theodore Ts'o#ifndef READ_ONLY
144050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'ostatic void make_link(char *sourcename, char *destname)
14413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1442abdf84f38ae766f401961d82d4eefdad78ac24edTheodore Ts'o	ext2_ino_t	ino;
1443abdf84f38ae766f401961d82d4eefdad78ac24edTheodore Ts'o	struct ext2_inode inode;
1444b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	int		retval;
1445b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	ext2_ino_t	dir;
1446d4e0b1c6f5aa8c6a248d9149ed5634a310952411Theodore Ts'o	char		*dest, *cp, *base_name;
14473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
14483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	/*
14493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	 * Get the source inode
14503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	 */
1451abdf84f38ae766f401961d82d4eefdad78ac24edTheodore Ts'o	ino = string_to_inode(sourcename);
1452abdf84f38ae766f401961d82d4eefdad78ac24edTheodore Ts'o	if (!ino)
14533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
1454d4e0b1c6f5aa8c6a248d9149ed5634a310952411Theodore Ts'o	base_name = strrchr(sourcename, '/');
1455d4e0b1c6f5aa8c6a248d9149ed5634a310952411Theodore Ts'o	if (base_name)
1456d4e0b1c6f5aa8c6a248d9149ed5634a310952411Theodore Ts'o		base_name++;
14573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else
1458d4e0b1c6f5aa8c6a248d9149ed5634a310952411Theodore Ts'o		base_name = sourcename;
14593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	/*
14603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	 * Figure out the destination.  First see if it exists and is
1461efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o	 * a directory.
14623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	 */
1463fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	if (! (retval=ext2fs_namei(current_fs, root, cwd, destname, &dir)))
1464d4e0b1c6f5aa8c6a248d9149ed5634a310952411Theodore Ts'o		dest = base_name;
14653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else {
14663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		/*
14673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		 * OK, it doesn't exist.  See if it is
14683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		 * '<dir>/basename' or 'basename'
14693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		 */
14703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		cp = strrchr(destname, '/');
14713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (cp) {
14723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			*cp = 0;
14733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			dir = string_to_inode(destname);
14743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			if (!dir)
14753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				return;
14763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			dest = cp+1;
14773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		} else {
14783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			dir = cwd;
14793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			dest = destname;
14803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
14813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1482abdf84f38ae766f401961d82d4eefdad78ac24edTheodore Ts'o
1483abdf84f38ae766f401961d82d4eefdad78ac24edTheodore Ts'o	if (debugfs_read_inode(ino, &inode, sourcename))
1484abdf84f38ae766f401961d82d4eefdad78ac24edTheodore Ts'o		return;
1485efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1486efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o	retval = ext2fs_link(current_fs, dir, dest, ino,
1487abdf84f38ae766f401961d82d4eefdad78ac24edTheodore Ts'o			     ext2_file_type(inode.i_mode));
14883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (retval)
14899b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o		com_err("make_link", retval, 0);
14903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return;
14913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
14923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
14933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
14943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_link(int argc, char *argv[])
14953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1496e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (common_args_process(argc, argv, 3, 3, "link",
1497e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o				"<source file> <dest_name>", CHECK_FS_RW))
1498e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		return;
1499e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o
1500e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	make_link(argv[1], argv[2]);
1501e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o}
1502e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o
1503048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Hensonstatic int mark_blocks_proc(ext2_filsys fs, blk64_t *blocknr,
1504048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			    e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
1505048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			    blk64_t ref_block EXT2FS_ATTR((unused)),
1506048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			    int ref_offset EXT2FS_ATTR((unused)),
1507544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o			    void *private EXT2FS_ATTR((unused)))
1508e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o{
1509048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	blk64_t	block;
1510e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o
1511e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	block = *blocknr;
1512048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	ext2fs_block_alloc_stats2(fs, block, +1);
1513e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	return 0;
1514e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o}
1515e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o
1516e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'ovoid do_undel(int argc, char *argv[])
1517e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o{
1518e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	ext2_ino_t	ino;
1519e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	struct ext2_inode inode;
1520e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o
1521b026d539e67ca4bd1a7ef3743888c594fad7bfffTheodore Ts'o	if (common_args_process(argc, argv, 2, 3, "undelete",
1522b026d539e67ca4bd1a7ef3743888c594fad7bfffTheodore Ts'o				"<inode_num> [dest_name]",
1523e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o				CHECK_FS_RW | CHECK_FS_BITMAPS))
1524e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		return;
1525e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o
1526e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	ino = string_to_inode(argv[1]);
1527e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (!ino)
1528e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		return;
1529e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o
1530e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (debugfs_read_inode(ino, &inode, argv[1]))
1531e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		return;
1532e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o
15336d879a999bad95724304a2a5158d7da4fcd599e7Valerie Aurora Henson	if (ext2fs_test_inode_bitmap2(current_fs->inode_map, ino)) {
1534e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		com_err(argv[1], 0, "Inode is not marked as deleted");
15353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
15363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1537e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o
1538e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	/*
1539e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	 * XXX this function doesn't handle changing the links count on the
1540efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o	 * parent directory when undeleting a directory.
1541e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	 */
1542e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	inode.i_links_count = LINUX_S_ISDIR(inode.i_mode) ? 2 : 1;
1543e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	inode.i_dtime = 0;
1544e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o
1545e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (debugfs_write_inode(ino, &inode, argv[0]))
15463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
15473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1548048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	ext2fs_block_iterate3(current_fs, ino, BLOCK_FLAG_READ_ONLY, NULL,
1549048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			      mark_blocks_proc, NULL);
1550e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o
1551d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	ext2fs_inode_alloc_stats2(current_fs, ino, +1, 0);
1552e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o
1553b026d539e67ca4bd1a7ef3743888c594fad7bfffTheodore Ts'o	if (argc > 2)
1554b026d539e67ca4bd1a7ef3743888c594fad7bfffTheodore Ts'o		make_link(argv[1], argv[2]);
15553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
15563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
155750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'ostatic void unlink_file_by_name(char *filename)
15583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1559b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	int		retval;
1560b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	ext2_ino_t	dir;
1561d4e0b1c6f5aa8c6a248d9149ed5634a310952411Theodore Ts'o	char		*base_name;
1562efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1563d4e0b1c6f5aa8c6a248d9149ed5634a310952411Theodore Ts'o	base_name = strrchr(filename, '/');
1564d4e0b1c6f5aa8c6a248d9149ed5634a310952411Theodore Ts'o	if (base_name) {
1565d4e0b1c6f5aa8c6a248d9149ed5634a310952411Theodore Ts'o		*base_name++ = '\0';
15663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		dir = string_to_inode(filename);
15673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (!dir)
15683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			return;
15693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	} else {
15703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		dir = cwd;
1571d4e0b1c6f5aa8c6a248d9149ed5634a310952411Theodore Ts'o		base_name = filename;
15723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1573d4e0b1c6f5aa8c6a248d9149ed5634a310952411Theodore Ts'o	retval = ext2fs_unlink(current_fs, dir, base_name, 0, 0);
15743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (retval)
15759b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o		com_err("unlink_file_by_name", retval, 0);
15763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return;
15773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
15783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
15793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_unlink(int argc, char *argv[])
15803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1581e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (common_args_process(argc, argv, 2, 2, "link",
1582e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o				"<pathname>", CHECK_FS_RW))
15833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
15843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
15853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	unlink_file_by_name(argv[1]);
15863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
1587b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o
1588b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'ovoid do_copy_inode(int argc, char *argv[])
1589b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o{
1590b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o	ext2_ino_t	src_ino, dest_ino;
1591b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o	struct ext2_inode inode;
1592b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o	unsigned char	buf[4096];
1593b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o	int		retval;
1594b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o
1595b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o	if (common_args_process(argc, argv, 3, 3, "copy_inode",
1596b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o				"<source file> <dest_name>", CHECK_FS_RW))
1597b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o		return;
1598b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o
1599b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o	src_ino = string_to_inode(argv[1]);
1600b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o	if (!src_ino)
1601b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o		return;
1602b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o
1603b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o	dest_ino = string_to_inode(argv[2]);
1604b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o	if (!dest_ino)
1605b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o		return;
1606b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o
1607b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o	if (debugfs_read_inode_full(src_ino, (struct ext2_inode *) buf,
1608b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o				    argv[0], sizeof(buf)))
1609b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o		return;
1610b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o
1611b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o	if (debugfs_write_inode_full(dest_ino, (struct ext2_inode *) buf,
1612b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o				     argv[0], sizeof(buf)))
1613b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o		return;
1614b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o}
1615b199291909e5951b74c9ad43163b5022a329dc26Theodore Ts'o
1616e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#endif /* READ_ONLY */
16173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
16183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_find_free_block(int argc, char *argv[])
16193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1620048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	blk64_t	free_blk, goal, first_free = 0;
1621e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o 	int		count;
16223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	errcode_t	retval;
16233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	char		*tmp;
1624efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1625e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if ((argc > 3) || (argc==2 && *argv[1] == '?')) {
1626e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		com_err(argv[0], 0, "Usage: find_free_block [count [goal]]");
16273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
16283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
16293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (check_fs_open(argv[0]))
16303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
16313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
16323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (argc > 1) {
1633e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		count = strtol(argv[1],&tmp,0);
1634e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		if (*tmp) {
1635e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o			com_err(argv[0], 0, "Bad count - %s", argv[1]);
1636e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o			return;
1637e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		}
1638e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o 	} else
1639e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		count = 1;
1640e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o
1641e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (argc > 2) {
1642e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		goal = strtol(argv[2], &tmp, 0);
16433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (*tmp) {
16443839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			com_err(argv[0], 0, "Bad goal - %s", argv[1]);
16453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			return;
16463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
16473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
16483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else
1649fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		goal = current_fs->super->s_first_data_block;
16503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1651e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	printf("Free blocks found: ");
1652efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o	free_blk = goal - 1;
1653e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	while (count-- > 0) {
1654048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson		retval = ext2fs_new_block2(current_fs, free_blk + 1, 0,
1655048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson					   &free_blk);
16565aae7c292fe0e10ec4e36d664da86939d15aca31Theodore Ts'o		if (first_free) {
16575aae7c292fe0e10ec4e36d664da86939d15aca31Theodore Ts'o			if (first_free == free_blk)
16585aae7c292fe0e10ec4e36d664da86939d15aca31Theodore Ts'o				break;
16595aae7c292fe0e10ec4e36d664da86939d15aca31Theodore Ts'o		} else
16605aae7c292fe0e10ec4e36d664da86939d15aca31Theodore Ts'o			first_free = free_blk;
1661e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		if (retval) {
16629b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o			com_err("ext2fs_new_block", retval, 0);
1663e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o			return;
1664e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		} else
1665048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			printf("%llu ", free_blk);
1666e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	}
1667e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o 	printf("\n");
16683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
16693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
16703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_find_free_inode(int argc, char *argv[])
16713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1672b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	ext2_ino_t	free_inode, dir;
1673b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	int		mode;
1674b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	int		retval;
1675b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	char		*tmp;
1676efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
167750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	if (argc > 3 || (argc>1 && *argv[1] == '?')) {
167850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		com_err(argv[0], 0, "Usage: find_free_inode [dir] [mode]");
16793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
16803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
16813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (check_fs_open(argv[0]))
16823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
16833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
16843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (argc > 1) {
16853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		dir = strtol(argv[1], &tmp, 0);
16863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (*tmp) {
16873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			com_err(argv[0], 0, "Bad dir - %s", argv[1]);
16883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			return;
16893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
16903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
16913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else
16923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		dir = root;
16933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (argc > 2) {
16943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		mode = strtol(argv[2], &tmp, 0);
16953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (*tmp) {
16963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			com_err(argv[0], 0, "Bad mode - %s", argv[2]);
16973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			return;
16983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
169950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	} else
17003839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		mode = 010755;
17013839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1702fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	retval = ext2fs_new_inode(current_fs, dir, mode, 0, &free_inode);
17033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (retval)
17049b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o		com_err("ext2fs_new_inode", retval, 0);
17053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else
1706b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o		printf("Free inode found: %u\n", free_inode);
17073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
17083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1709e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#ifndef READ_ONLY
171050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'ovoid do_write(int argc, char *argv[])
171150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o{
1712b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	errcode_t	retval;
171350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
1714e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (common_args_process(argc, argv, 3, 3, "write",
1715e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o				"<native file> <new file>", CHECK_FS_RW))
171650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		return;
1717e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o
1718a3111e80b82d28e2ad5c8ad74bc4acecf559d1d4Darrick J. Wong	retval = do_write_internal(current_fs, cwd, argv[1], argv[2], root);
1719a3111e80b82d28e2ad5c8ad74bc4acecf559d1d4Darrick J. Wong	if (retval)
17209b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o		com_err(argv[0], retval, 0);
172150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o}
172250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
172350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'ovoid do_mknod(int argc, char *argv[])
172450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o{
1725c4c9bc590c4a1f21ec3053aacc232430493f10b0Darrick J. Wong	unsigned long	major, minor;
1726b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	errcode_t 	retval;
1727c4c9bc590c4a1f21ec3053aacc232430493f10b0Darrick J. Wong	int		nr;
17289aa3aa8dae4781b7d03c4d086fc3d27fb3fd2351Robert Yang	struct stat	st;
172950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
173050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	if (check_fs_open(argv[0]))
173150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		return;
173250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	if (argc < 3 || argv[2][1]) {
1733e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	usage:
173450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		com_err(argv[0], 0, "Usage: mknod <name> [p| [c|b] <major> <minor>]");
173550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		return;
173650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	}
17379aa3aa8dae4781b7d03c4d086fc3d27fb3fd2351Robert Yang
1738c4c9bc590c4a1f21ec3053aacc232430493f10b0Darrick J. Wong	minor = major = 0;
173950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	switch (argv[2][0]) {
174050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		case 'p':
17419aa3aa8dae4781b7d03c4d086fc3d27fb3fd2351Robert Yang			st.st_mode = S_IFIFO;
174250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			nr = 3;
174350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			break;
174450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		case 'c':
17459aa3aa8dae4781b7d03c4d086fc3d27fb3fd2351Robert Yang			st.st_mode = S_IFCHR;
174650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			nr = 5;
174750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			break;
174850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		case 'b':
17499aa3aa8dae4781b7d03c4d086fc3d27fb3fd2351Robert Yang			st.st_mode = S_IFBLK;
175050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			nr = 5;
175150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			break;
175250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		default:
175350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			nr = 0;
175450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	}
17559aa3aa8dae4781b7d03c4d086fc3d27fb3fd2351Robert Yang
175650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	if (nr == 5) {
175750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		major = strtoul(argv[3], argv+3, 0);
175850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		minor = strtoul(argv[4], argv+4, 0);
17592d10769ec6745b1e4bab371764d65bb3587ab285Theodore Ts'o		if (major > 65535 || minor > 65535 || argv[3][0] || argv[4][0])
176050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			nr = 0;
176150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	}
17629aa3aa8dae4781b7d03c4d086fc3d27fb3fd2351Robert Yang
1763e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (argc != nr)
1764e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		goto usage;
17659aa3aa8dae4781b7d03c4d086fc3d27fb3fd2351Robert Yang
17669aa3aa8dae4781b7d03c4d086fc3d27fb3fd2351Robert Yang	st.st_rdev = makedev(major, minor);
1767a3111e80b82d28e2ad5c8ad74bc4acecf559d1d4Darrick J. Wong	retval = do_mknod_internal(current_fs, cwd, argv[1], &st);
1768a3111e80b82d28e2ad5c8ad74bc4acecf559d1d4Darrick J. Wong	if (retval)
17699b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o		com_err(argv[0], retval, 0);
177050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o}
177150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
17723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_mkdir(int argc, char *argv[])
17733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
17743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	errcode_t retval;
17753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1776e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (common_args_process(argc, argv, 2, 2, "mkdir",
1777e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o				"<filename>", CHECK_FS_RW))
1778d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o		return;
1779d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o
178025f291c9b32d8017e6969c72a75e37d354c0570bTheodore Ts'o	retval = do_mkdir_internal(current_fs, cwd, argv[1], root);
1781a3111e80b82d28e2ad5c8ad74bc4acecf559d1d4Darrick J. Wong	if (retval)
17829aa3aa8dae4781b7d03c4d086fc3d27fb3fd2351Robert Yang		com_err(argv[0], retval, 0);
17833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
17843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
17853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1786048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Hensonstatic int release_blocks_proc(ext2_filsys fs, blk64_t *blocknr,
1787048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			       e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
1788048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			       blk64_t ref_block EXT2FS_ATTR((unused)),
1789048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			       int ref_offset EXT2FS_ATTR((unused)),
1790544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o			       void *private EXT2FS_ATTR((unused)))
17913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1792048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	blk64_t	block;
1793344368911e118ffacde509d63bb8e617f91ea7cfTheodore Ts'o
1794344368911e118ffacde509d63bb8e617f91ea7cfTheodore Ts'o	block = *blocknr;
1795048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	ext2fs_block_alloc_stats2(fs, block, -1);
17963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
17973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
17983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1799b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'ostatic void kill_file_by_inode(ext2_ino_t inode)
18003839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
18013839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	struct ext2_inode inode_buf;
18023839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1803e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (debugfs_read_inode(inode, &inode_buf, 0))
1804e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		return;
18054efae606bf3159f2134fa29a5ad78fb9f6331f92Theodore Ts'o	inode_buf.i_dtime = current_fs->now ? current_fs->now : time(0);
1806e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (debugfs_write_inode(inode, &inode_buf, 0))
1807e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o		return;
1808716a3c3536f87372ce16b5b678b9957dabf6d638Zheng Liu	if (ext2fs_inode_has_valid_blocks2(current_fs, &inode_buf)) {
1809716a3c3536f87372ce16b5b678b9957dabf6d638Zheng Liu		ext2fs_block_iterate3(current_fs, inode, BLOCK_FLAG_READ_ONLY,
1810716a3c3536f87372ce16b5b678b9957dabf6d638Zheng Liu				      NULL, release_blocks_proc, NULL);
1811716a3c3536f87372ce16b5b678b9957dabf6d638Zheng Liu	}
1812521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o	printf("\n");
1813d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	ext2fs_inode_alloc_stats2(current_fs, inode, -1,
1814d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o				  LINUX_S_ISDIR(inode_buf.i_mode));
18153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
18163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
18173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
18183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_kill_file(int argc, char *argv[])
18193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1820b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	ext2_ino_t inode_num;
18213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1822e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (common_inode_args_process(argc, argv, &inode_num, CHECK_FS_RW))
18233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
18243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
18253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	kill_file_by_inode(inode_num);
18263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
18273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
18283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_rm(int argc, char *argv[])
18293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
18303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int retval;
1831b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	ext2_ino_t inode_num;
18323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	struct ext2_inode inode;
18333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1834e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (common_args_process(argc, argv, 2, 2, "rm",
1835e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o				"<filename>", CHECK_FS_RW))
1836d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o		return;
1837d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o
1838fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	retval = ext2fs_namei(current_fs, root, cwd, argv[1], &inode_num);
18393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (retval) {
184091d6d486d259b6eb08e4999025b9ef2b097d3495Theodore Ts'o		com_err(argv[0], retval, "while trying to resolve filename");
18413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
18423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
18433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1844e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (debugfs_read_inode(inode_num, &inode, argv[0]))
18453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
18463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
184750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	if (LINUX_S_ISDIR(inode.i_mode)) {
18483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		com_err(argv[0], 0, "file is a directory");
18493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
18503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
18513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
18523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	--inode.i_links_count;
1853e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (debugfs_write_inode(inode_num, &inode, argv[0]))
18543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
18553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
18563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	unlink_file_by_name(argv[1]);
18573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (inode.i_links_count == 0)
18583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		kill_file_by_inode(inode_num);
18593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
18603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1861d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'ostruct rd_struct {
1862d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	ext2_ino_t	parent;
1863d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	int		empty;
1864d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o};
1865d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o
1866544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'ostatic int rmdir_proc(ext2_ino_t dir EXT2FS_ATTR((unused)),
1867544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		      int	entry EXT2FS_ATTR((unused)),
1868d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		      struct ext2_dir_entry *dirent,
1869544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		      int	offset EXT2FS_ATTR((unused)),
1870544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		      int	blocksize EXT2FS_ATTR((unused)),
1871544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		      char	*buf EXT2FS_ATTR((unused)),
1872d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		      void	*private)
1873d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o{
1874d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	struct rd_struct *rds = (struct rd_struct *) private;
1875d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o
1876d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	if (dirent->inode == 0)
1877d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		return 0;
187870f4632b626e3db94dd02c9dc9b4e643ffb0d048Jan Kara	if ((ext2fs_dirent_name_len(dirent) == 1) && (dirent->name[0] == '.'))
1879d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		return 0;
188070f4632b626e3db94dd02c9dc9b4e643ffb0d048Jan Kara	if ((ext2fs_dirent_name_len(dirent) == 2) && (dirent->name[0] == '.') &&
1881d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	    (dirent->name[1] == '.')) {
1882d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		rds->parent = dirent->inode;
1883d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		return 0;
1884d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	}
1885d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	rds->empty = 0;
1886d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	return 0;
1887d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o}
1888efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1889d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'ovoid do_rmdir(int argc, char *argv[])
1890d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o{
1891d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	int retval;
1892d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	ext2_ino_t inode_num;
1893d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	struct ext2_inode inode;
1894d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	struct rd_struct rds;
1895d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o
1896d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	if (common_args_process(argc, argv, 2, 2, "rmdir",
1897d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o				"<filename>", CHECK_FS_RW))
1898d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		return;
1899d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o
1900d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	retval = ext2fs_namei(current_fs, root, cwd, argv[1], &inode_num);
1901d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	if (retval) {
1902d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		com_err(argv[0], retval, "while trying to resolve filename");
1903d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		return;
1904d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	}
1905d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o
1906d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	if (debugfs_read_inode(inode_num, &inode, argv[0]))
1907d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		return;
1908d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o
1909d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	if (!LINUX_S_ISDIR(inode.i_mode)) {
1910d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		com_err(argv[0], 0, "file is not a directory");
1911d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		return;
1912d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	}
1913d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o
1914d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	rds.parent = 0;
1915d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	rds.empty = 1;
1916d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o
1917d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	retval = ext2fs_dir_iterate2(current_fs, inode_num, 0,
1918d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o				    0, rmdir_proc, &rds);
1919d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	if (retval) {
1920d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		com_err(argv[0], retval, "while iterating over directory");
1921d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		return;
1922d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	}
1923d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	if (rds.empty == 0) {
1924d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		com_err(argv[0], 0, "directory not empty");
1925d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		return;
1926d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	}
1927d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o
1928d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	inode.i_links_count = 0;
1929d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	if (debugfs_write_inode(inode_num, &inode, argv[0]))
1930d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		return;
1931d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o
1932d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	unlink_file_by_name(argv[1]);
1933d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	kill_file_by_inode(inode_num);
1934d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o
1935d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	if (rds.parent) {
1936d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		if (debugfs_read_inode(rds.parent, &inode, argv[0]))
1937d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o			return;
1938d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		if (inode.i_links_count > 1)
1939d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o			inode.i_links_count--;
1940d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o		if (debugfs_write_inode(rds.parent, &inode, argv[0]))
1941d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o			return;
1942d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o	}
1943d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o}
1944e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#endif /* READ_ONLY */
1945d7f64ae8386bf94ec7490459c9fa0fb2b0b95e0fTheodore Ts'o
1946efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ovoid do_show_debugfs_params(int argc EXT2FS_ATTR((unused)),
1947544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o			    char *argv[] EXT2FS_ATTR((unused)))
19483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1949fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	if (current_fs)
19501d520184ee1a809f0a41566eed80ccf64b39ed1aZheng Liu		printf("Open mode: read-%s\n",
19511d520184ee1a809f0a41566eed80ccf64b39ed1aZheng Liu		       current_fs->flags & EXT2_FLAG_RW ? "write" : "only");
19521d520184ee1a809f0a41566eed80ccf64b39ed1aZheng Liu	printf("Filesystem in use: %s\n",
19531d520184ee1a809f0a41566eed80ccf64b39ed1aZheng Liu	       current_fs ? current_fs->device_name : "--none--");
19543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
19553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1956e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#ifndef READ_ONLY
19573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid do_expand_dir(int argc, char *argv[])
19583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1959b044c2e02af46c54206f0f6e29896ab32681a7dbTheodore Ts'o	ext2_ino_t inode;
19603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int retval;
19613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1962e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o	if (common_inode_args_process(argc, argv, &inode, CHECK_FS_RW))
19633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
19643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1965fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	retval = ext2fs_expand_dir(current_fs, inode);
19663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (retval)
19679b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o		com_err("ext2fs_expand_dir", retval, 0);
19683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return;
19693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
19703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1971d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'ovoid do_features(int argc, char *argv[])
1972d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o{
1973d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o	int	i;
1974efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1975d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o	if (check_fs_open(argv[0]))
1976d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o		return;
1977d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o
1978d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o	if ((argc != 1) && check_fs_read_write(argv[0]))
1979d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o		return;
1980d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o	for (i=1; i < argc; i++) {
1981d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o		if (e2p_edit_feature(argv[i],
198206968e7e27aaac0f28fc6448fef58fcda314b5a2Theodore Ts'o				     &current_fs->super->s_feature_compat, 0))
1983d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o			com_err(argv[0], 0, "Unknown feature: %s\n",
1984d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o				argv[i]);
1985d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o		else
1986d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o			ext2fs_mark_super_dirty(current_fs);
1987d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o	}
19885dd8f963d04fa4099a003cb3b13ffae05ab29210Theodore Ts'o	print_features(current_fs->super, stdout);
1989d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o}
1990e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#endif /* READ_ONLY */
1991d3aea7dc1bf155861573ae16160a703b03527ac9Theodore Ts'o
1992b38cd283637dafff6b39d4b76bf76fa2789eb21fTheodore Ts'ovoid do_bmap(int argc, char *argv[])
1993b38cd283637dafff6b39d4b76bf76fa2789eb21fTheodore Ts'o{
1994b38cd283637dafff6b39d4b76bf76fa2789eb21fTheodore Ts'o	ext2_ino_t	ino;
19959ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o	blk64_t		blk, pblk = 0;
19969ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o	int		c, err, flags = 0, ret_flags = 0;
1997b38cd283637dafff6b39d4b76bf76fa2789eb21fTheodore Ts'o	errcode_t	errcode;
1998efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
19999ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o	if (check_fs_open(argv[0]))
2000b38cd283637dafff6b39d4b76bf76fa2789eb21fTheodore Ts'o		return;
2001b38cd283637dafff6b39d4b76bf76fa2789eb21fTheodore Ts'o
20029ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o	reset_getopt();
20039ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o	while ((c = getopt (argc, argv, "a")) != EOF) {
20049ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o		switch (c) {
20059ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o		case 'a':
20069ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o			flags |= BMAP_ALLOC;
20079ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o			break;
20089ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o		default:
20099ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o			goto print_usage;
20109ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o		}
20119ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o	}
20129ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o
20139ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o	if (argc <= optind+1) {
20149ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o	print_usage:
20159ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o		com_err(0, 0,
20169ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o			"Usage: bmap [-a] <file> logical_blk [physical_blk]");
20179ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o		return;
20189ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o	}
20199ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o
20209ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o	ino = string_to_inode(argv[optind++]);
2021becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o	if (!ino)
2022becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o		return;
20239ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o	err = strtoblk(argv[0], argv[optind++], "logical block", &blk);
2024fe56188b07668758c28912b6eaf31abb498a9e82Darrick J. Wong	if (err)
2025fe56188b07668758c28912b6eaf31abb498a9e82Darrick J. Wong		return;
2026b38cd283637dafff6b39d4b76bf76fa2789eb21fTheodore Ts'o
20279ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o	if (argc > optind+1)
20289ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o		goto print_usage;
20299ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o
20309ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o	if (argc == optind+1) {
20319ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o		err = strtoblk(argv[0], argv[optind++],
20329ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o			       "physical block", &pblk);
20339ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o		if (err)
20349ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o			return;
20359ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o		if (flags & BMAP_ALLOC) {
20369ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o			com_err(0, 0, "Can't set and allocate a block");
20379ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o			return;
20389ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o		}
20399ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o		flags |= BMAP_SET;
20409ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o	}
20419ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o
20429ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o	errcode = ext2fs_bmap2(current_fs, ino, 0, 0, flags, blk,
20439ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o			       &ret_flags, &pblk);
2044b38cd283637dafff6b39d4b76bf76fa2789eb21fTheodore Ts'o	if (errcode) {
204550295a3f9e40894316301bebcc7247e9ec85f506Darrick J. Wong		com_err(argv[0], errcode,
2046048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson			"while mapping logical block %llu\n", blk);
2047b38cd283637dafff6b39d4b76bf76fa2789eb21fTheodore Ts'o		return;
2048b38cd283637dafff6b39d4b76bf76fa2789eb21fTheodore Ts'o	}
20499ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o	printf("%llu", pblk);
20509ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o	if (ret_flags & BMAP_RET_UNINIT)
20519ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o		fputs(" (uninit)", stdout);
20529ed2c124f3245f48f45e52285c1e6dd55390d2a2Theodore Ts'o	fputc('\n', stdout);
2053b38cd283637dafff6b39d4b76bf76fa2789eb21fTheodore Ts'o}
2054b38cd283637dafff6b39d4b76bf76fa2789eb21fTheodore Ts'o
2055becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'ovoid do_imap(int argc, char *argv[])
2056becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o{
2057becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o	ext2_ino_t	ino;
2058becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o	unsigned long 	group, block, block_nr, offset;
2059becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o
2060becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o	if (common_args_process(argc, argv, 2, 2, argv[0],
2061becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o				"<file>", 0))
2062becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o		return;
2063becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o	ino = string_to_inode(argv[1]);
2064becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o	if (!ino)
206588494bb6d440f703db98b6cc4452f63d7aa392b9Theodore Ts'o		return;
2066becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o
2067becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o	group = (ino - 1) / EXT2_INODES_PER_GROUP(current_fs->super);
2068becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o	offset = ((ino - 1) % EXT2_INODES_PER_GROUP(current_fs->super)) *
2069becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o		EXT2_INODE_SIZE(current_fs->super);
2070becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o	block = offset >> EXT2_BLOCK_SIZE_BITS(current_fs->super);
2071048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	if (!ext2fs_inode_table_loc(current_fs, (unsigned)group)) {
2072544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		com_err(argv[0], 0, "Inode table for group %lu is missing\n",
2073becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o			group);
2074becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o		return;
2075becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o	}
2076048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	block_nr = ext2fs_inode_table_loc(current_fs, (unsigned)group) +
2077becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o		block;
2078becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o	offset &= (EXT2_BLOCK_SIZE(current_fs->super) - 1);
2079becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o
208048e6e81362f264aee4f3945c14928efaf71a06c9Theodore Ts'o	printf("Inode %d is part of block group %lu\n"
208148e6e81362f264aee4f3945c14928efaf71a06c9Theodore Ts'o	       "\tlocated at block %lu, offset 0x%04lx\n", ino, group,
2082becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o	       block_nr, offset);
2083becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o
2084becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o}
2085becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o
2086e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wongvoid do_idump(int argc, char *argv[])
2087e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong{
2088e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong	ext2_ino_t	ino;
20890befec4e24377e391dca2a3f9e6e163f18b132ceAndreas Dilger	unsigned char	*buf;
2090e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong	errcode_t	err;
2091e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong	int		isize;
2092e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong
2093e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong	if (common_args_process(argc, argv, 2, 2, argv[0],
2094e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong				"<file>", 0))
2095e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong		return;
2096e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong	ino = string_to_inode(argv[1]);
2097e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong	if (!ino)
2098e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong		return;
2099e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong
2100e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong	isize = EXT2_INODE_SIZE(current_fs->super);
2101e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong	err = ext2fs_get_mem(isize, &buf);
2102e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong	if (err) {
2103e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong		com_err(argv[0], err, "while allocating memory");
2104e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong		return;
2105e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong	}
2106e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong
2107e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong	err = ext2fs_read_inode_full(current_fs, ino,
2108e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong				     (struct ext2_inode *)buf, isize);
2109e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong	if (err) {
2110e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong		com_err(argv[0], err, "while reading inode %d", ino);
2111e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong		goto err;
2112e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong	}
2113e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong
2114e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong	do_byte_hexdump(stdout, buf, isize);
2115e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wongerr:
2116e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong	ext2fs_free_mem(&buf);
2117e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong}
2118e13ebfdd5f13876de1b978c8a5ed5a322ed7ba62Darrick J. Wong
2119e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#ifndef READ_ONLY
21204efae606bf3159f2134fa29a5ad78fb9f6331f92Theodore Ts'ovoid do_set_current_time(int argc, char *argv[])
21214efae606bf3159f2134fa29a5ad78fb9f6331f92Theodore Ts'o{
2122188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o	__s64 now;
21234efae606bf3159f2134fa29a5ad78fb9f6331f92Theodore Ts'o
21244efae606bf3159f2134fa29a5ad78fb9f6331f92Theodore Ts'o	if (common_args_process(argc, argv, 2, 2, argv[0],
21254efae606bf3159f2134fa29a5ad78fb9f6331f92Theodore Ts'o				"<time>", 0))
21264efae606bf3159f2134fa29a5ad78fb9f6331f92Theodore Ts'o		return;
2127becf36f6ace508fd091052b9e9bcdea192bfbc48Theodore Ts'o
21284efae606bf3159f2134fa29a5ad78fb9f6331f92Theodore Ts'o	now = string_to_time(argv[1]);
2129188960ea4b830ec69607aab3068537ce55f44be4Theodore Ts'o	if (now == -1) {
21304efae606bf3159f2134fa29a5ad78fb9f6331f92Theodore Ts'o		com_err(argv[0], 0, "Couldn't parse argument as a time: %s\n",
21314efae606bf3159f2134fa29a5ad78fb9f6331f92Theodore Ts'o			argv[1]);
21324efae606bf3159f2134fa29a5ad78fb9f6331f92Theodore Ts'o		return;
21334efae606bf3159f2134fa29a5ad78fb9f6331f92Theodore Ts'o
21344efae606bf3159f2134fa29a5ad78fb9f6331f92Theodore Ts'o	} else {
21354efae606bf3159f2134fa29a5ad78fb9f6331f92Theodore Ts'o		printf("Setting current time to %s\n", time_to_string(now));
21364efae606bf3159f2134fa29a5ad78fb9f6331f92Theodore Ts'o		current_fs->now = now;
21374efae606bf3159f2134fa29a5ad78fb9f6331f92Theodore Ts'o	}
21384efae606bf3159f2134fa29a5ad78fb9f6331f92Theodore Ts'o}
2139e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#endif /* READ_ONLY */
2140b38cd283637dafff6b39d4b76bf76fa2789eb21fTheodore Ts'o
214103efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilgerstatic int find_supp_feature(__u32 *supp, int feature_type, char *name)
214203efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger{
214303efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger	int compat, bit, ret;
214403efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger	unsigned int feature_mask;
214503efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger
214603efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger	if (name) {
214703efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger		if (feature_type == E2P_FS_FEATURE)
214803efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger			ret = e2p_string2feature(name, &compat, &feature_mask);
214903efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger		else
215003efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger			ret = e2p_jrnl_string2feature(name, &compat,
215103efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger						      &feature_mask);
215203efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger		if (ret)
215303efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger			return ret;
215403efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger
215503efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger		if (!(supp[compat] & feature_mask))
215603efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger			return 1;
215703efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger	} else {
215803efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger	        for (compat = 0; compat < 3; compat++) {
215903efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger		        for (bit = 0, feature_mask = 1; bit < 32;
216003efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger			     bit++, feature_mask <<= 1) {
216103efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger			        if (supp[compat] & feature_mask) {
216203efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger					if (feature_type == E2P_FS_FEATURE)
216303efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger						fprintf(stdout, " %s",
216403efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger						e2p_feature2string(compat,
216503efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger						feature_mask));
216603efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger					else
216703efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger						fprintf(stdout, " %s",
216803efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger						e2p_jrnl_feature2string(compat,
216903efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger						feature_mask));
217003efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger				}
217103efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger	        	}
217203efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger		}
217303efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger	        fprintf(stdout, "\n");
217403efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger	}
217503efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger
217603efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger	return 0;
217703efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger}
217803efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger
217903efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilgervoid do_supported_features(int argc, char *argv[])
218003efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger{
218142080a8656895eddb0e054c3af86667a5a6aff9fTheodore Ts'o        int	ret;
218203efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger	__u32	supp[3] = { EXT2_LIB_FEATURE_COMPAT_SUPP,
218303efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger			    EXT2_LIB_FEATURE_INCOMPAT_SUPP,
218403efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger			    EXT2_LIB_FEATURE_RO_COMPAT_SUPP };
218503efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger	__u32	jrnl_supp[3] = { JFS_KNOWN_COMPAT_FEATURES,
218603efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger				 JFS_KNOWN_INCOMPAT_FEATURES,
218703efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger				 JFS_KNOWN_ROCOMPAT_FEATURES };
218803efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger
218903efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger	if (argc > 1) {
219003efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger		ret = find_supp_feature(supp, E2P_FS_FEATURE, argv[1]);
219103efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger		if (ret) {
219203efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger			ret = find_supp_feature(jrnl_supp, E2P_JOURNAL_FEATURE,
219303efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger						argv[1]);
219403efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger		}
219503efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger		if (ret)
219603efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger			com_err(argv[0], 0, "Unknown feature: %s\n", argv[1]);
219703efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger		else
219803efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger			fprintf(stdout, "Supported feature: %s\n", argv[1]);
219903efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger	} else {
220003efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger		fprintf(stdout, "Supported features:");
220103efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger		ret = find_supp_feature(supp, E2P_FS_FEATURE, NULL);
220203efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger		ret = find_supp_feature(jrnl_supp, E2P_JOURNAL_FEATURE, NULL);
220303efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger	}
220403efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger}
220503efde8abe79c80ff369206d06d4f1e476b08f53Andreas Dilger
2206e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#ifndef READ_ONLY
220786685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'ovoid do_punch(int argc, char *argv[])
220886685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o{
220986685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o	ext2_ino_t	ino;
221086685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o	blk64_t		start, end;
221186685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o	int		err;
221286685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o	errcode_t	errcode;
221386685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o
221486685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o	if (common_args_process(argc, argv, 3, 4, argv[0],
221586685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o				"<file> start_blk [end_blk]",
221686685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o				CHECK_FS_RW | CHECK_FS_BITMAPS))
221786685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o		return;
221886685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o
221986685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o	ino = string_to_inode(argv[1]);
222086685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o	if (!ino)
222186685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o		return;
2222a25fffae5cbdb9349fa3c358c9714584e9de7b33Eric Whitney	err = strtoblk(argv[0], argv[2], "logical block", &start);
2223fe56188b07668758c28912b6eaf31abb498a9e82Darrick J. Wong	if (err)
2224fe56188b07668758c28912b6eaf31abb498a9e82Darrick J. Wong		return;
2225fe56188b07668758c28912b6eaf31abb498a9e82Darrick J. Wong	if (argc == 4) {
2226a25fffae5cbdb9349fa3c358c9714584e9de7b33Eric Whitney		err = strtoblk(argv[0], argv[3], "logical block", &end);
2227fe56188b07668758c28912b6eaf31abb498a9e82Darrick J. Wong		if (err)
2228fe56188b07668758c28912b6eaf31abb498a9e82Darrick J. Wong			return;
2229fe56188b07668758c28912b6eaf31abb498a9e82Darrick J. Wong	} else
223086685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o		end = ~0;
223186685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o
223286685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o	errcode = ext2fs_punch(current_fs, ino, 0, 0, start, end);
223386685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o
223486685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o	if (errcode) {
223586685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o		com_err(argv[0], errcode,
223686685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o			"while truncating inode %u from %llu to %llu\n", ino,
223786685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o			(unsigned long long) start, (unsigned long long) end);
223886685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o		return;
223986685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o	}
224086685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o}
22412f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong
22422f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wongvoid do_fallocate(int argc, char *argv[])
22432f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong{
22442f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong	ext2_ino_t	ino;
22452f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong	blk64_t		start, end;
22462f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong	int		err;
22472f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong	errcode_t	errcode;
22482f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong
22492f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong	if (common_args_process(argc, argv, 3, 4, argv[0],
22502f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong				"<file> start_blk [end_blk]",
22512f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong				CHECK_FS_RW | CHECK_FS_BITMAPS))
22522f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong		return;
22532f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong
22542f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong	ino = string_to_inode(argv[1]);
22552f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong	if (!ino)
22562f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong		return;
22572f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong	err = strtoblk(argv[0], argv[2], "logical block", &start);
22582f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong	if (err)
22592f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong		return;
22602f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong	if (argc == 4) {
22612f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong		err = strtoblk(argv[0], argv[3], "logical block", &end);
22622f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong		if (err)
22632f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong			return;
22642f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong	} else
22652f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong		end = ~0;
22662f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong
22672f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong	errcode = ext2fs_fallocate(current_fs, EXT2_FALLOCATE_INIT_BEYOND_EOF,
22682f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong				   ino, NULL, ~0ULL, start, end - start + 1);
22692f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong
22702f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong	if (errcode) {
22712f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong		com_err(argv[0], errcode,
22722f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong			"while fallocating inode %u from %llu to %llu\n", ino,
22732f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong			(unsigned long long) start, (unsigned long long) end);
22742f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong		return;
22752f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong	}
22762f8c0d028cd8e3b24aaa357a796478c3435e21e4Darrick J. Wong}
2277e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#endif /* READ_ONLY */
227886685923625eed3632eaf17cdda8e86f13b13384Theodore Ts'o
22794df6a37bd39c84ea67394ab5049bc82f14b929b5Darren Hartvoid do_symlink(int argc, char *argv[])
22804df6a37bd39c84ea67394ab5049bc82f14b929b5Darren Hart{
22814df6a37bd39c84ea67394ab5049bc82f14b929b5Darren Hart	errcode_t	retval;
22824df6a37bd39c84ea67394ab5049bc82f14b929b5Darren Hart
22834df6a37bd39c84ea67394ab5049bc82f14b929b5Darren Hart	if (common_args_process(argc, argv, 3, 3, "symlink",
22844df6a37bd39c84ea67394ab5049bc82f14b929b5Darren Hart				"<filename> <target>", CHECK_FS_RW))
22854df6a37bd39c84ea67394ab5049bc82f14b929b5Darren Hart		return;
22864df6a37bd39c84ea67394ab5049bc82f14b929b5Darren Hart
2287a3111e80b82d28e2ad5c8ad74bc4acecf559d1d4Darrick J. Wong	retval = do_symlink_internal(current_fs, cwd, argv[1], argv[2], root);
2288a3111e80b82d28e2ad5c8ad74bc4acecf559d1d4Darrick J. Wong	if (retval)
22899aa3aa8dae4781b7d03c4d086fc3d27fb3fd2351Robert Yang		com_err(argv[0], retval, 0);
22904df6a37bd39c84ea67394ab5049bc82f14b929b5Darren Hart
22914df6a37bd39c84ea67394ab5049bc82f14b929b5Darren Hart}
22924df6a37bd39c84ea67394ab5049bc82f14b929b5Darren Hart
229325f291c9b32d8017e6969c72a75e37d354c0570bTheodore Ts'o#if CONFIG_MMP
22943cebf9c1029ca983ebbbae79f7905a02d087ff98Theodore Ts'ovoid do_dump_mmp(int argc EXT2FS_ATTR((unused)), char *argv[])
22950f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger{
22960f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger	struct mmp_struct *mmp_s;
22972fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger	unsigned long long mmp_block;
22980f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger	time_t t;
22990f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger	errcode_t retval = 0;
23000f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger
23017105c183a0f4622268a50db37017cfacc9877e5fEric Sandeen	if (check_fs_open(argv[0]))
23027105c183a0f4622268a50db37017cfacc9877e5fEric Sandeen		return;
23037105c183a0f4622268a50db37017cfacc9877e5fEric Sandeen
23042fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger	if (argc > 1) {
23052fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger		char *end = NULL;
23062fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger		mmp_block = strtoull(argv[1], &end, 0);
23072fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger		if (end == argv[0] || mmp_block == 0) {
23082fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger			fprintf(stderr, "%s: invalid MMP block '%s' given\n",
23092fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger				argv[0], argv[1]);
23102fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger			return;
23112fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger		}
23122fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger	} else {
23132fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger		mmp_block = current_fs->super->s_mmp_block;
23142fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger	}
23152fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger
23162fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger	if (mmp_block == 0) {
23172fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger		fprintf(stderr, "%s: MMP: not active on this filesystem.\n",
23182fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger			argv[0]);
23192fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger		return;
23202fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger	}
23212fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger
23220f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger	if (current_fs->mmp_buf == NULL) {
23230f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger		retval = ext2fs_get_mem(current_fs->blocksize,
23240f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger					&current_fs->mmp_buf);
23250f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger		if (retval) {
23260f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger			com_err(argv[0], retval, "allocating MMP buffer.\n");
23270f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger			return;
23280f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger		}
23290f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger	}
23300f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger
23310f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger	mmp_s = current_fs->mmp_buf;
23320f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger
23332fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger	retval = ext2fs_mmp_read(current_fs, mmp_block, current_fs->mmp_buf);
23340f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger	if (retval) {
23352fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger		com_err(argv[0], retval, "reading MMP block %llu.\n",
23362fe6136c48610791de8bb4c8fcad536292ffe36eAndreas Dilger			mmp_block);
23370f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger		return;
23380f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger	}
23390f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger
23400f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger	t = mmp_s->mmp_time;
23410f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger	fprintf(stdout, "block_number: %llu\n", current_fs->super->s_mmp_block);
23420f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger	fprintf(stdout, "update_interval: %d\n",
23430f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger		current_fs->super->s_mmp_update_interval);
23440f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger	fprintf(stdout, "check_interval: %d\n", mmp_s->mmp_check_interval);
23450f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger	fprintf(stdout, "sequence: %08x\n", mmp_s->mmp_seq);
23460f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger	fprintf(stdout, "time: %lld -- %s", mmp_s->mmp_time, ctime(&t));
23470f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger	fprintf(stdout, "node_name: %s\n", mmp_s->mmp_nodename);
23480f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger	fprintf(stdout, "device_name: %s\n", mmp_s->mmp_bdevname);
23497105c183a0f4622268a50db37017cfacc9877e5fEric Sandeen	fprintf(stdout, "magic: 0x%x\n", mmp_s->mmp_magic);
2350a9620d8b308271ace63dd0787555fa715d09e0f8Darrick J. Wong	fprintf(stdout, "checksum: 0x%08x\n", mmp_s->mmp_checksum);
235125f291c9b32d8017e6969c72a75e37d354c0570bTheodore Ts'o	fprintf(stdout, "MMP is unsupported, please recompile with "
235225f291c9b32d8017e6969c72a75e37d354c0570bTheodore Ts'o	                "--enable-mmp\n");
235325f291c9b32d8017e6969c72a75e37d354c0570bTheodore Ts'o}
2354d6a4bcb517ac7aa6d2347d6979f1f04cd94d60d8Tony Breeds#else
235525f291c9b32d8017e6969c72a75e37d354c0570bTheodore Ts'ovoid do_dump_mmp(int argc EXT2FS_ATTR((unused)),
235625f291c9b32d8017e6969c72a75e37d354c0570bTheodore Ts'o		 char *argv[] EXT2FS_ATTR((unused)))
235725f291c9b32d8017e6969c72a75e37d354c0570bTheodore Ts'o{
2358d6a4bcb517ac7aa6d2347d6979f1f04cd94d60d8Tony Breeds	fprintf(stdout, "MMP is unsupported, please recompile with "
2359d6a4bcb517ac7aa6d2347d6979f1f04cd94d60d8Tony Breeds	                "--enable-mmp\n");
23600f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger}
236125f291c9b32d8017e6969c72a75e37d354c0570bTheodore Ts'o#endif
23620f5eba7501f467f757792ee449d16c9259b994fdAndreas Dilger
23639e85208e84bbdea9cfe6e8887502a1c4d92efbe5Theodore Ts'ostatic int source_file(const char *cmd_file, int ss_idx)
2364fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o{
2365fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	FILE		*f;
2366355ffb2ff566229b8bc3f5f7557e91edff5a767aRobert Yang	char		buf[BUFSIZ];
2367fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	char		*cp;
2368fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	int		exit_status = 0;
2369fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	int		retval;
2370fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o
2371fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	if (strcmp(cmd_file, "-") == 0)
2372fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		f = stdin;
2373fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	else {
2374fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		f = fopen(cmd_file, "r");
2375fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		if (!f) {
2376fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o			perror(cmd_file);
2377fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o			exit(1);
2378fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		}
2379fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	}
23802a7bfe835317bb9f3ebcd20079b2bb800f4b9eaaTheodore Ts'o	fflush(stdout);
23812a7bfe835317bb9f3ebcd20079b2bb800f4b9eaaTheodore Ts'o	fflush(stderr);
2382fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	setbuf(stdout, NULL);
2383fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	setbuf(stderr, NULL);
2384fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	while (!feof(f)) {
2385fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		if (fgets(buf, sizeof(buf), f) == NULL)
2386fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o			break;
2387fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		cp = strchr(buf, '\n');
2388fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		if (cp)
2389fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o			*cp = 0;
2390fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		cp = strchr(buf, '\r');
2391fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		if (cp)
2392fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o			*cp = 0;
2393fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		printf("debugfs: %s\n", buf);
23949e85208e84bbdea9cfe6e8887502a1c4d92efbe5Theodore Ts'o		retval = ss_execute_line(ss_idx, buf);
2395fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		if (retval) {
23969e85208e84bbdea9cfe6e8887502a1c4d92efbe5Theodore Ts'o			ss_perror(ss_idx, retval, buf);
2397fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o			exit_status++;
2398fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		}
2399fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	}
24002d7ef236b752c1da7868f009018075fddc01d810Peng Tao	if (f != stdin)
24012d7ef236b752c1da7868f009018075fddc01d810Peng Tao		fclose(f);
2402fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	return exit_status;
2403fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o}
2404fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o
2405a8859cad8790514cf2c41507aaea1ff3b751b954Theodore Ts'oint main(int argc, char **argv)
24063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
240750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	int		retval;
2408e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o	const char	*usage =
2409e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o		"Usage: %s [-b blocksize] [-s superblock] [-f cmd_file] "
2410e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o		"[-R request] [-V] ["
2411e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#ifndef READ_ONLY
2412491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong		"[-w] [-z undo_file] "
2413e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#endif
2414e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o		"[-c] device]";
2415f13048113f09def05a024470bfeaf44635bf7e98Theodore Ts'o	int		c;
241603b9dca63a75731711071e0a7ddef0475d6daf3aEric Sandeen	int		open_flags = EXT2_FLAG_SOFTSUPP_FEATURES | EXT2_FLAG_64BITS;
2417fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	char		*request = 0;
2418fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	int		exit_status = 0;
2419fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	char		*cmd_file = 0;
2420048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	blk64_t		superblock = 0;
2421048786d7e87a6de698936b0cf25f1ab70d5c15bcValerie Aurora Henson	blk64_t		blocksize = 0;
24222e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o	int		catastrophic = 0;
24231ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o	char		*data_filename = 0;
2424e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#ifdef READ_ONLY
24259bca9a39b7b159d78f21ddab63ba1ad68c5e5443Darrick J. Wong	const char	*opt_string = "nicR:f:b:s:Vd:D";
2426e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#else
2427491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	const char	*opt_string = "niwcR:f:b:s:Vd:Dz:";
2428491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong	char		*undo_file = NULL;
2429e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#endif
24301fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o#ifdef CONFIG_JBD_DEBUG
24311fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o	char		*jbd_debug;
24321fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o#endif
2433efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
243449ce6cb5cee956a478a3704c92619de1c7f204d5Theodore Ts'o	if (debug_prog_name == 0)
2435e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#ifdef READ_ONLY
2436e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o		debug_prog_name = "rdebugfs";
2437e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#else
243849ce6cb5cee956a478a3704c92619de1c7f204d5Theodore Ts'o		debug_prog_name = "debugfs";
2439e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#endif
2440a6d8302b4873527798a77c1ba3106a04b71dfeacTheodore Ts'o	add_error_table(&et_ext2_error_table);
244149ce6cb5cee956a478a3704c92619de1c7f204d5Theodore Ts'o	fprintf (stderr, "%s %s (%s)\n", debug_prog_name,
244249ce6cb5cee956a478a3704c92619de1c7f204d5Theodore Ts'o		 E2FSPROGS_VERSION, E2FSPROGS_DATE);
24433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
24441fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o#ifdef CONFIG_JBD_DEBUG
24451fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o	jbd_debug = ss_safe_getenv("DEBUGFS_JBD_DEBUG");
24461fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o	if (jbd_debug) {
24471fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o		int res = sscanf(jbd_debug, "%d", &journal_enable_debug);
24481fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o
24491fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o		if (res != 1) {
24501fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o			fprintf(stderr,
24511fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o				"DEBUGFS_JBD_DEBUG \"%s\" not an integer\n\n",
24521fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o				jbd_debug);
24531fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o			exit(1);
24541fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o		}
24551fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o	}
24561fc23b5e773a7a30130842a8091af546d5dd9875Theodore Ts'o#endif
2457e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o	while ((c = getopt (argc, argv, opt_string)) != EOF) {
24583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		switch (c) {
2459fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		case 'R':
2460fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o			request = optarg;
2461fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o			break;
2462fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		case 'f':
2463fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o			cmd_file = optarg;
2464fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o			break;
24651ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o		case 'd':
24661ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o			data_filename = optarg;
24671ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o			break;
246859cf7e0da802aa8f560434bd521c30f5bb5d3e21Theodore Ts'o		case 'i':
246959cf7e0da802aa8f560434bd521c30f5bb5d3e21Theodore Ts'o			open_flags |= EXT2_FLAG_IMAGE_FILE;
247059cf7e0da802aa8f560434bd521c30f5bb5d3e21Theodore Ts'o			break;
24719bca9a39b7b159d78f21ddab63ba1ad68c5e5443Darrick J. Wong		case 'n':
24729bca9a39b7b159d78f21ddab63ba1ad68c5e5443Darrick J. Wong			open_flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
24739bca9a39b7b159d78f21ddab63ba1ad68c5e5443Darrick J. Wong			break;
2474e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#ifndef READ_ONLY
24753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		case 'w':
247659cf7e0da802aa8f560434bd521c30f5bb5d3e21Theodore Ts'o			open_flags |= EXT2_FLAG_RW;
24773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			break;
2478e88c5a33a841026728fa7c9fcc4bcdca6580b495Theodore Ts'o#endif
24790fd68e0241e944545d43045593e82b0fb7317797Theodore Ts'o		case 'D':
24800fd68e0241e944545d43045593e82b0fb7317797Theodore Ts'o			open_flags |= EXT2_FLAG_DIRECT_IO;
24810fd68e0241e944545d43045593e82b0fb7317797Theodore Ts'o			break;
24822e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		case 'b':
2483efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o			blocksize = parse_ulong(optarg, argv[0],
2484e1018eeaa3285cd0ca26986d929194c1b577d211Theodore Ts'o						"block size", 0);
24852e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o			break;
24862e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		case 's':
2487a25fffae5cbdb9349fa3c358c9714584e9de7b33Eric Whitney			retval = strtoblk(argv[0], optarg,
2488a25fffae5cbdb9349fa3c358c9714584e9de7b33Eric Whitney					  "superblock block number",
2489a25fffae5cbdb9349fa3c358c9714584e9de7b33Eric Whitney					  &superblock);
249032541fe4f90e59597f7721967153e9641c5f8dceEric Whitney			if (retval)
2491fe56188b07668758c28912b6eaf31abb498a9e82Darrick J. Wong				return 1;
24922e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o			break;
24932e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		case 'c':
24942e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o			catastrophic = 1;
24952e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o			break;
2496818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'o		case 'V':
2497818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'o			/* Print version number and exit */
2498818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'o			fprintf(stderr, "\tUsing %s\n",
2499818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'o				error_message(EXT2_ET_BASE));
2500818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'o			exit(0);
2501491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong		case 'z':
2502491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong			undo_file = optarg;
2503491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong			break;
25043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		default:
250549ce6cb5cee956a478a3704c92619de1c7f204d5Theodore Ts'o			com_err(argv[0], 0, usage, debug_prog_name);
2506b4ac9cc351ba9613347a1f60a6e7d9c91060df82Theodore Ts'o			return 1;
25073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
25083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
25093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (optind < argc)
25102e8d40d562ec93d68505800a46c5b9dcc229264eTheodore Ts'o		open_filesystem(argv[optind], open_flags,
25111ad54a940c499a66241f624882f1ffa03ce56d90Theodore Ts'o				superblock, blocksize, catastrophic,
2512491cc33ac6895d228b731e037b311e4314d72b88Darrick J. Wong				data_filename, undo_file);
2513efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
251449ce6cb5cee956a478a3704c92619de1c7f204d5Theodore Ts'o	sci_idx = ss_create_invocation(debug_prog_name, "0.0", (char *) NULL,
25153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				       &debug_cmds, &retval);
25163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (retval) {
25173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		ss_perror(sci_idx, retval, "creating invocation");
25183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		exit(1);
25193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
25203ae497eab281eab5f98770e6a3d5992b9d37325eTheodore Ts'o	ss_get_readline(sci_idx);
25213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
25223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	(void) ss_add_request_table (sci_idx, &ss_std_requests, 1, &retval);
25233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (retval) {
25243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		ss_perror(sci_idx, retval, "adding standard requests");
25253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		exit (1);
25263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
252749ce6cb5cee956a478a3704c92619de1c7f204d5Theodore Ts'o	if (extra_cmds)
252849ce6cb5cee956a478a3704c92619de1c7f204d5Theodore Ts'o		ss_add_request_table (sci_idx, extra_cmds, 1, &retval);
252949ce6cb5cee956a478a3704c92619de1c7f204d5Theodore Ts'o	if (retval) {
253049ce6cb5cee956a478a3704c92619de1c7f204d5Theodore Ts'o		ss_perror(sci_idx, retval, "adding extra requests");
253149ce6cb5cee956a478a3704c92619de1c7f204d5Theodore Ts'o		exit (1);
253249ce6cb5cee956a478a3704c92619de1c7f204d5Theodore Ts'o	}
2533fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	if (request) {
2534fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		retval = 0;
2535fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		retval = ss_execute_line(sci_idx, request);
2536fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		if (retval) {
2537fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o			ss_perror(sci_idx, retval, request);
2538fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o			exit_status++;
2539fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		}
2540fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	} else if (cmd_file) {
2541fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		exit_status = source_file(cmd_file, sci_idx);
2542fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	} else {
2543fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o		ss_listen(sci_idx);
2544fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	}
25453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
25466e9761c2c02a055199059156a979e5d9928c428bTheodore Ts'o	ss_delete_invocation(sci_idx);
25476e9761c2c02a055199059156a979e5d9928c428bTheodore Ts'o
2548fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o	if (current_fs)
25493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		close_filesystem();
2550efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
2551a6d8302b4873527798a77c1ba3106a04b71dfeacTheodore Ts'o	remove_error_table(&et_ext2_error_table);
2552e597304ab282d3030cbe364a6c55b9fe803a86c0Theodore Ts'o	return exit_status;
25533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
2554