From: Aneesh Kumar K.V <aneesh.kumar@xxxxxxxxxxxxxxxxxx> When running mke2fs, if a file system is detected on the device, we use Undo I/O manager as the io manager. This helps in reverting the changes made to the filesystem in case we wrongly selected the device. The environment variable MKE2FS_SCRATCH_DIR is used to indicate the directory within which the tdb file need to be created. The file will be named mke2fs-XXXXXX If MKE2FS_SCRATCH_DIR is not set /var/lib/e2fsprogs is used Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@xxxxxxxxxxxxxxxxxx> --- misc/mke2fs.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 108 insertions(+), 1 deletions(-) diff --git a/misc/mke2fs.c b/misc/mke2fs.c index 0c6d4f3..3ff4b90 100644 --- a/misc/mke2fs.c +++ b/misc/mke2fs.c @@ -44,6 +44,7 @@ extern int optind; #endif #include <sys/ioctl.h> #include <sys/types.h> +#include <libgen.h> #include "ext2fs/ext2_fs.h" #include "et/com_err.h" @@ -1521,6 +1522,102 @@ static void PRS(int argc, char *argv[]) fs_param.s_blocks_count); } +static int filesystem_exist(const char *name) +{ + errcode_t retval; + io_channel channel; + __u16 s_magic; + struct ext2_super_block super; + io_manager manager = unix_io_manager; + + retval = manager->open(name, IO_FLAG_EXCLUSIVE, &channel); + if (retval) { + /* + * We don't handle error cases instead we + * declare that the file system doesn't exist + * and let the rest of mke2fs take care of + * error + */ + retval = 0; + goto open_err_out; + } + + io_channel_set_blksize(channel, SUPERBLOCK_OFFSET); + retval = io_channel_read_blk(channel, 1, -SUPERBLOCK_SIZE, &super); + if (retval) { + retval = 0; + goto err_out; + } + +#if defined(WORDS_BIGENDIAN) + s_magic = ext2fs_swab16(super.s_magic); +#else + s_magic = super.s_magic; +#endif + + if (s_magic == EXT2_SUPER_MAGIC) + retval = 1; + +err_out: + io_channel_close(channel); + +open_err_out: + + return retval; +} + +static int mke2fs_setup_tdb(const char *name) +{ + errcode_t retval = 0; + char *tdb_dir, tdb_file[PATH_MAX]; + char *device_name, *tmp_name; + +#if 0 /* FIXME!! */ + /* + * Configuration via a conf file would be + * nice + */ + profile_get_string(profile, "scratch_files", + "directory", 0, 0, + &tdb_dir); +#endif + tmp_name = strdup(name); + device_name = basename(tmp_name); + + tdb_dir = getenv("MKE2FS_SCRATCH_DIR"); + if (!tdb_dir) { + printf(_("MKE2FS_SCRATCH_DIR not configured\n")); + printf(_("Using /var/lib/e2fsprogs\n")); + tdb_dir="/var/lib/e2fsprogs"; + } + if (access(tdb_dir, W_OK)) { + fprintf(stderr, + _("Cannot create file under %s\n"), + tdb_dir); + retval = EXT2_ET_INVALID_ARGUMENT; + goto err_out; + + } + + sprintf(tdb_file, "%s/mke2fs-%s", tdb_dir, device_name); + + if (!access(tdb_file, F_OK)) { + fprintf(stderr, + _("File exist %s\n"), tdb_file); + retval = EXT2_ET_INVALID_ARGUMENT; + goto err_out; + } + + set_undo_io_backup_file(tdb_file); + printf(_("previous filesystem detected; to undo " + "the mke2fs operation, please run the " + "command \n'undoe2fs %s %s' in order to recover\n\n"), + tdb_file, name); +err_out: + free(tmp_name); + return retval; +} + int main (int argc, char *argv[]) { errcode_t retval = 0; @@ -1543,7 +1640,17 @@ int main (int argc, char *argv[]) io_ptr = test_io_manager; test_io_backing_manager = unix_io_manager; #else - io_ptr = unix_io_manager; + if (filesystem_exist(device_name)) { + + io_ptr = undo_io_manager; + set_undo_io_backing_manager(unix_io_manager); + retval = mke2fs_setup_tdb(device_name); + if (retval) + exit(1); + + } else { + io_ptr = unix_io_manager; + } #endif /* -- 1.5.3.rc2.22.g69a9b-dirty - To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html