AC_CHECK_LIB(blkid, blkid_probe_get_topology,
AC_DEFINE(HAVE_BLKID_PROBE_GET_TOPOLOGY, 1,
[Define to 1 if blkid has blkid_probe_get_topology]))
+ AC_CHECK_LIB(blkid, blkid_topology_get_dax,
+ AC_DEFINE(HAVE_BLKID_TOPOLOGY_GET_DAX, 1,
+ [Define to 1 if blkid has blkid_topology_get_dax]))
AC_CHECK_LIB(blkid, blkid_probe_enable_partitions,
AC_DEFINE(HAVE_BLKID_PROBE_ENABLE_PARTITIONS, 1,
[Define to 1 if blkid has blkid_probe_enable_partitions]))
return;
break;
case 'z':
+#ifdef READ_ONLY
+ goto print_usage;
+#else
undo_file = optarg;
+#endif
break;
default:
goto print_usage;
print_usage:
fprintf(stderr, "%s: Usage: open [-s superblock] [-b blocksize] "
+#ifdef READ_ONLY
"[-d image_filename] [-z undo_file] [-c] [-i] [-f] [-e] [-D] "
-#ifndef READ_ONLY
- "[-w] "
+#else
+ "[-d image_filename] [-c] [-i] [-f] [-e] [-D] [-w] "
#endif
"<device>\n", argv[0]);
}
return;
}
}
-#endif /* READ_ONLY */
void do_symlink(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
void *infop EXT2FS_ATTR((unused)))
com_err(argv[0], retval, 0);
}
+#endif /* READ_ONLY */
#if CONFIG_MMP
void do_dump_mmp(int argc EXT2FS_ATTR((unused)), char *argv[],
const char *opt_string = "nicR:f:b:s:Vd:D";
#else
const char *opt_string = "niwcR:f:b:s:Vd:Dz:";
- char *undo_file = NULL;
#endif
+ char *undo_file = NULL;
#ifdef CONFIG_JBD_DEBUG
char *jbd_debug;
#endif
fprintf(stderr, "\tUsing %s\n",
error_message(EXT2_ET_BASE));
exit(0);
+#ifndef READ_ONLY
case 'z':
undo_file = optarg;
break;
+#endif
default:
com_err(argv[0], 0, usage, debug_prog_name);
return 1;
/* util.c */
extern __s64 string_to_time(const char *arg);
-errcode_t read_list(char *str, blk64_t **list, size_t *len);
+extern errcode_t read_list(char *str, blk64_t **list, size_t *len);
+extern void do_byte_hexdump(FILE *fp, unsigned char *buf, size_t bufsize);
/* xattrs.c */
void dump_inode_attributes(FILE *out, ext2_ino_t ino);
/* zap.c */
extern void do_zap_block(int argc, char **argv, int sci_idx, void *infop);
extern void do_block_dump(int argc, char **argv, int sci_idx, void *infop);
-extern void do_byte_hexdump(FILE *fp, unsigned char *buf, size_t bufsize);
free(lst);
return retval;
}
+
+void do_byte_hexdump(FILE *fp, unsigned char *buf, size_t bufsize)
+{
+ size_t i, j, max;
+ int suppress = -1;
+
+ for (i = 0; i < bufsize; i += 16) {
+ max = (bufsize - i > 16) ? 16 : bufsize - i;
+ if (suppress < 0) {
+ if (i && memcmp(buf + i, buf + i - max, max) == 0) {
+ suppress = i;
+ fprintf(fp, "*\n");
+ continue;
+ }
+ } else {
+ if (memcmp(buf + i, buf + suppress, max) == 0)
+ continue;
+ suppress = -1;
+ }
+ fprintf(fp, "%04o ", (unsigned int)i);
+ for (j = 0; j < 16; j++) {
+ if (j < max)
+ fprintf(fp, "%02x", buf[i+j]);
+ else
+ fprintf(fp, " ");
+ if ((j % 2) == 1)
+ fprintf(fp, " ");
+ }
+ fprintf(fp, " ");
+ for (j = 0; j < max; j++)
+ fprintf(fp, "%c", isprint(buf[i+j]) ? buf[i+j] : '.');
+ fprintf(fp, "\n");
+ }
+ fprintf(fp, "\n");
+}
errout:
free(buf);
}
-
-void do_byte_hexdump(FILE *fp, unsigned char *buf, size_t bufsize)
-{
- size_t i, j, max;
- int suppress = -1;
-
- for (i = 0; i < bufsize; i += 16) {
- max = (bufsize - i > 16) ? 16 : bufsize - i;
- if (suppress < 0) {
- if (i && memcmp(buf + i, buf + i - max, max) == 0) {
- suppress = i;
- fprintf(fp, "*\n");
- continue;
- }
- } else {
- if (memcmp(buf + i, buf + suppress, max) == 0)
- continue;
- suppress = -1;
- }
- fprintf(fp, "%04o ", (unsigned int)i);
- for (j = 0; j < 16; j++) {
- if (j < max)
- fprintf(fp, "%02x", buf[i+j]);
- else
- fprintf(fp, " ");
- if ((j % 2) == 1)
- fprintf(fp, " ");
- }
- fprintf(fp, " ");
- for (j = 0; j < max; j++)
- fprintf(fp, "%c", isprint(buf[i+j]) ? buf[i+j] : '.');
- fprintf(fp, "\n");
- }
- fprintf(fp, "\n");
-}
extern void e2fsck_read_bitmaps(e2fsck_t ctx);
extern void e2fsck_write_bitmaps(e2fsck_t ctx);
extern void preenhalt(e2fsck_t ctx);
-extern char *string_copy(e2fsck_t ctx, const char *str, int len);
+extern char *string_copy(e2fsck_t ctx, const char *str, size_t len);
extern int fs_proc_check(const char *fs_name);
extern int check_for_modules(const char *fs_name);
#ifdef RESOURCE_TRACK
return 1;
pctx->num = root->indirect_levels;
- if ((root->indirect_levels > ext2_dir_htree_level(fs)) &&
+ if ((root->indirect_levels >= ext2_dir_htree_level(fs)) &&
fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
return 1;
void *priv_data)
{
struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data;
- struct hash_entry *new_array, *ent;
+ struct hash_entry *ent;
struct ext2_dir_entry *dirent;
char *dir;
unsigned int offset, dir_offset, rec_len, name_len;
struct hash_entry *ent;
struct ext2_dir_entry *dirent;
unsigned int rec_len, prev_rec_len, left, slack, offset;
- int i;
+ blk_t i;
ext2_dirhash_t prev_hash;
int csum_size = 0;
struct ext2_dir_entry_tail *t;
fputs("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n",
ctx->problem_logf);
fprintf(ctx->problem_logf, "<problem_log time=\"%lu\">\n",
- ctx->now);
+ (unsigned long) ctx->now);
fprintf(ctx->problem_logf, "<invocation prog=\"%s\"",
argv[0]);
for (i = 1; i < argc; i++)
char buf[256];
#ifdef DEBUG_ALLOCATE_MEMORY
- printf("Allocating %u bytes for %s...\n", size, description);
+ printf("Allocating %lu bytes for %s...\n", size, description);
#endif
if (ext2fs_get_memzero(size, &ret)) {
- sprintf(buf, "Can't allocate %u bytes for %s\n",
+ sprintf(buf, "Can't allocate %lu bytes for %s\n",
size, description);
fatal_error(ctx, buf);
}
}
char *string_copy(e2fsck_t ctx EXT2FS_ATTR((unused)),
- const char *str, int len)
+ const char *str, size_t len)
{
char *ret;
#define kbytes(x) (((unsigned long long)(x) + 1023) / 1024)
#ifdef HAVE_MALLINFO
/* don't use mallinfo() if over 2GB used, since it returns "int" */
- if ((char *)sbrk(0) - (char *)track->brk_start < 2ULL << 30) {
+ if ((char *)sbrk(0) - (char *)track->brk_start < 2LL << 30) {
struct mallinfo malloc_info = mallinfo();
log_out(ctx, _("Memory used: %lluk/%lluk (%lluk/%lluk), "),
{ EXT2_TOPDIR_FL, "T", "Top_of_Directory_Hierarchies" },
{ EXT4_EXTENTS_FL, "e", "Extents" },
{ FS_NOCOW_FL, "C", "No_COW" },
+ { FS_DAX_FL, "x", "DAX" },
{ EXT4_CASEFOLD_FL, "F", "Casefold" },
{ EXT4_INLINE_DATA_FL, "N", "Inline_Data" },
{ EXT4_PROJINHERIT_FL, "P", "Project_Hierarchy" },
d = dirent;
top = EXT2_DIRENT_TAIL(dirent, fs->blocksize);
- rec_len = translate(d->rec_len);
while ((void *) d < top) {
+ rec_len = translate(d->rec_len);
if ((rec_len < 8) || (rec_len & 0x03))
return EXT2_ET_DIR_CORRUPTED;
d = (struct ext2_dir_entry *)(((char *)d) + rec_len);
- rec_len = translate(d->rec_len);
}
- if ((void *)d > ((void *)dirent + fs->blocksize))
+ if ((char *)d > ((char *)dirent + fs->blocksize))
return EXT2_ET_DIR_CORRUPTED;
if (d != top)
return EXT2_ET_DIR_NO_SPACE_FOR_CSUM;
/* EXT4_EOFBLOCKS_FL 0x00400000 was here */
#define FS_NOCOW_FL 0x00800000 /* Do not cow file */
#define EXT4_SNAPFILE_FL 0x01000000 /* Inode is a snapshot */
+#define FS_DAX_FL 0x02000000 /* Inode is DAX */
#define EXT4_SNAPFILE_DELETED_FL 0x04000000 /* Snapshot is being deleted */
#define EXT4_SNAPFILE_SHRUNK_FL 0x08000000 /* Snapshot shrink has completed */
#define EXT4_INLINE_DATA_FL 0x10000000 /* Inode has inline data */
blk64_t start, blk64_t len)
{
struct ext2_inode inode_buf;
- blk64_t blk, x;
+ blk64_t blk, x, zero_blk, last = 0;
+ int zero_len = 0;
errcode_t err;
if (((flags & EXT2_FALLOCATE_FORCE_INIT) &&
if (x)
continue;
- err = ext2fs_bmap2(fs, ino, inode, NULL,
- BMAP_ALLOC | BMAP_UNINIT | BMAP_ZERO, blk,
- 0, &x);
+ err = ext2fs_bmap2(fs, ino, inode, NULL, BMAP_ALLOC,
+ blk, 0, &x);
if (err)
- return err;
+ goto errout;
+ if ((zero_len && (x != last+1)) ||
+ (zero_len >= 65536)) {
+ err = ext2fs_zero_blocks2(fs, zero_blk, zero_len,
+ NULL, NULL);
+ zero_len = 0;
+ if (err)
+ goto errout;
+ }
+ if (zero_len == 0) {
+ zero_blk = x;
+ zero_len = 1;
+ } else {
+ zero_len++;
+ }
+ last = x;
}
out:
if (inode == &inode_buf)
ext2fs_write_inode(fs, ino, inode);
+errout:
+ if (zero_len)
+ ext2fs_zero_blocks2(fs, zero_blk, zero_len, NULL, NULL);
return err;
}
blk64_t blk;
ssize_t actual;
errcode_t retval;
- loff_t r;
+ ext2_loff_t r;
buf = malloc(fs->blocksize * BUF_BLOCKS);
if (!buf)
int j;
#endif
char *time_env;
+ int csum_retries = 0;
EXT2_CHECK_MAGIC(manager, EXT2_ET_MAGIC_IO_MANAGER);
if (retval)
goto cleanup;
}
+retry:
retval = io_channel_read_blk(fs->io, superblock, -SUPERBLOCK_SIZE,
fs->super);
if (retval)
retval = 0;
if (!ext2fs_verify_csum_type(fs, fs->super))
retval = EXT2_ET_UNKNOWN_CSUM;
- if (!ext2fs_superblock_csum_verify(fs, fs->super))
+ if (!ext2fs_superblock_csum_verify(fs, fs->super)) {
+ if (csum_retries++ < 3)
+ goto retry;
retval = EXT2_ET_SB_CSUM_INVALID;
+ }
}
#ifdef WORDS_BIGENDIAN
{
errcode_t retval;
char *p, *end;
- unsigned int rec_len, left;
+ unsigned int rec_len;
struct ext2_dir_entry *dirent;
p = buf;
end = buf + size;
- left = size;
while (p < end) {
dirent = (struct ext2_dir_entry *) p;
retval = ext2fs_get_rec_len(fs, dirent, &rec_len);
.B chattr
changes the file attributes on a Linux file system.
.PP
-The format of a symbolic mode is +-=[aAcCdDeFijPsStTu].
+The format of a symbolic mode is +-=[aAcCdDeFijPsStTux].
.PP
The operator '+' causes the selected attributes to be added to the
existing attributes of the files; '-' causes them to be removed; and '='
causes them to be the only attributes that the files have.
.PP
-The letters 'aAcCdDeFijPsStTu' select the new attributes for the files:
+The letters 'aAcCdDeFijPsStTux' select the new attributes for the files:
append only (a),
no atime updates (A),
compressed (c),
synchronous updates (S),
no tail-merging (t),
top of directory hierarchy (T),
-and undeletable (u).
+undeletable (u),
+and direct access for files (x).
.PP
The following attributes are read-only, and may be listed by
.BR lsattr (1)
make sure to read the bugs and limitations section at the end of this
document.
.TP
+.B x
+The 'x' attribute can be set on a directory or file. If the attribute
+is set on an existing directory, it will be inherited by all files and
+subdirectories that are subsequently created in the directory. If an
+existing directory has contained some files and subdirectories, modifying
+the attribute on the parent directory doesn't change the attributes on
+these files and subdirectories.
+.TP
.B V
A file with the 'V' attribute set has fs-verity enabled. It cannot be
written to, and the filesystem will automatically verify all data read
static void usage(void)
{
fprintf(stderr,
- _("Usage: %s [-pRVf] [-+=aAcCdDeijPsStTuF] [-v version] files...\n"),
+ _("Usage: %s [-pRVf] [-+=aAcCdDeijPsStTuFx] [-v version] files...\n"),
program_name);
exit(1);
}
{ EXT2_NOTAIL_FL, 't' },
{ EXT2_TOPDIR_FL, 'T' },
{ FS_NOCOW_FL, 'C' },
+ { FS_DAX_FL, 'x' },
{ EXT4_CASEFOLD_FL, 'F' },
{ 0, 0 }
};
return err;
}
-static int is_hardlink(struct hdlinks_s *hdlinks, dev_t dev, ext2_ino_t ino)
+static int is_hardlink(struct hdlinks_s *hdlinks, dev_t dev, ino_t ino)
{
int i;
static double user_corrupt_pct = 0.0;
#if !defined HAVE_PWRITE64 && !defined HAVE_PWRITE
-static ssize_t my_pwrite(int fd, const void *buf, size_t count, off_t offset)
+static ssize_t my_pwrite(int fd, const void *buf, size_t count,
+ ext2_loff_t offset)
{
- if (lseek(fd, offset, SEEK_SET) < 0)
+ if (ext2fs_llseek(fd, offset, SEEK_SET) < 0)
return 0;
return write(fd, buf, count);
}
static errcode_t find_metadata_blocks(ext2_filsys fs, ext2fs_block_bitmap bmap,
- off_t *corrupt_bytes)
+ ext2_loff_t *corrupt_bytes)
{
dgrp_t i;
blk64_t b, c;
int flags, fd;
ext2_filsys fs = NULL;
ext2fs_block_bitmap corrupt_map;
- loff_t hsize, count, off, offset, corrupt_bytes;
+ ext2_loff_t hsize, count, off, offset, corrupt_bytes, i;
unsigned char c;
- loff_t i;
/* If mounted rw, force dryrun mode */
ret = ext2fs_check_if_mounted(fsname, &flags);
If one or more directory paths are specified, e4crypt will try to
set the policy of those directories to use the key just added by the
.B add_key
-command.
+command. If a salt was explicitly specified, then it will be used
+to derive the encryption key of those directories. Otherwise a
+directory-specific default salt will be used.
.TP
.B e4crypt get_policy \fIpath\fR ...
Print the policy for the directories specified on the command line.
#include <getopt.h>
#include <dirent.h>
#include <errno.h>
+#include <stdbool.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
static void do_add_key(int argc, char **argv, const struct cmd_desc *cmd)
{
struct salt *salt;
+ bool explicit_salt = false;
char *keyring = NULL;
int i, opt, pad = 4;
unsigned j;
pad = atoi(optarg);
break;
case 'S':
+ if (explicit_salt) {
+ fputs("May only provide -S once\n", stderr);
+ exit(1);
+ }
/* Salt value for passphrase. */
parse_salt(optarg, 0);
+ explicit_salt = true;
break;
case 'v':
options |= OPT_VERBOSE;
exit(1);
}
validate_paths(argc, argv, optind);
- for (i = optind; i < argc; i++)
- parse_salt(argv[i], PARSE_FLAGS_FORCE_FN);
+ if (!explicit_salt)
+ for (i = optind; i < argc; i++)
+ parse_salt(argv[i], PARSE_FLAGS_FORCE_FN);
printf("Enter passphrase (echo disabled): ");
get_passphrase(in_passphrase, sizeof(in_passphrase));
for (j = 0, salt = salt_list; j < num_salt; j++, salt++) {
generate_key_ref_str(salt);
insert_key_into_keyring(keyring, salt);
}
- if (optind != argc)
- set_policy(NULL, pad, argc, argv, optind);
+ if (optind != argc) {
+ salt = explicit_salt ? salt_list : NULL;
+ set_policy(salt, pad, argc, argv, optind);
+ }
clear_secrets();
exit(0);
}
extern const char *mke2fs_default_profile;
static const char *default_files[] = { "<default>", 0 };
+struct device_param {
+ unsigned long min_io; /* prefered minimum IO size */
+ unsigned long opt_io; /* optimal IO size */
+ unsigned long alignment_offset; /* alignment offset wrt physical block size */
+ unsigned int dax:1; /* supports dax? */
+};
+
#ifdef HAVE_BLKID_PROBE_GET_TOPOLOGY
/*
* Sets the geometry of a device (stripe/stride), and returns the
* device's alignment offset, if any, or a negative error.
*/
static int get_device_geometry(const char *file,
- struct ext2_super_block *param,
- unsigned int psector_size)
+ unsigned int blocksize,
+ unsigned int psector_size,
+ struct device_param *dev_param)
{
int rc = -1;
- unsigned int blocksize;
blkid_probe pr;
blkid_topology tp;
- unsigned long min_io;
- unsigned long opt_io;
struct stat statbuf;
+ memset(dev_param, 0, sizeof(*dev_param));
+
/* Nothing to do for a regular file */
if (!stat(file, &statbuf) && S_ISREG(statbuf.st_mode))
return 0;
if (!tp)
goto out;
- min_io = blkid_topology_get_minimum_io_size(tp);
- opt_io = blkid_topology_get_optimal_io_size(tp);
- blocksize = EXT2_BLOCK_SIZE(param);
- if ((min_io == 0) && (psector_size > blocksize))
- min_io = psector_size;
- if ((opt_io == 0) && min_io)
- opt_io = min_io;
- if ((opt_io == 0) && (psector_size > blocksize))
- opt_io = psector_size;
-
- /* setting stripe/stride to blocksize is pointless */
- if (min_io > blocksize)
- param->s_raid_stride = min_io / blocksize;
- if (opt_io > blocksize)
- param->s_raid_stripe_width = opt_io / blocksize;
-
- rc = blkid_topology_get_alignment_offset(tp);
+ dev_param->min_io = blkid_topology_get_minimum_io_size(tp);
+ dev_param->opt_io = blkid_topology_get_optimal_io_size(tp);
+ if ((dev_param->min_io == 0) && (psector_size > blocksize))
+ dev_param->min_io = psector_size;
+ if ((dev_param->opt_io == 0) && dev_param->min_io > 0)
+ dev_param->opt_io = dev_param->min_io;
+ if ((dev_param->opt_io == 0) && (psector_size > blocksize))
+ dev_param->opt_io = psector_size;
+
+ dev_param->alignment_offset = blkid_topology_get_alignment_offset(tp);
+#ifdef HAVE_BLKID_TOPOLOGY_GET_DAX
+ dev_param->dax = blkid_topology_get_dax(tp);
+#endif
+ rc = 0;
out:
blkid_free_probe(pr);
return rc;
int use_bsize;
char *newpath;
int pathlen = sizeof(PATH_SET) + 1;
+ struct device_param dev_param;
if (oldpath)
pathlen += strlen(oldpath);
}
#ifdef HAVE_BLKID_PROBE_GET_TOPOLOGY
- retval = get_device_geometry(device_name, &fs_param,
- (unsigned int) psector_size);
+ retval = get_device_geometry(device_name, blocksize,
+ psector_size, &dev_param);
if (retval < 0) {
fprintf(stderr,
_("warning: Unable to get device geometry for %s\n"),
device_name);
- } else if (retval) {
- printf(_("%s alignment is offset by %lu bytes.\n"),
- device_name, retval);
- printf(_("This may result in very poor performance, "
- "(re)-partitioning suggested.\n"));
+ } else {
+ /* setting stripe/stride to blocksize is pointless */
+ if (dev_param.min_io > blocksize)
+ fs_param.s_raid_stride = dev_param.min_io / blocksize;
+ if (dev_param.opt_io > blocksize) {
+ fs_param.s_raid_stripe_width =
+ dev_param.opt_io / blocksize;
+ }
+
+ if (dev_param.alignment_offset) {
+ printf(_("%s alignment is offset by %lu bytes.\n"),
+ device_name, dev_param.alignment_offset);
+ printf(_("This may result in very poor performance, "
+ "(re)-partitioning suggested.\n"));
+ }
+
+ if (dev_param.dax && blocksize != sys_page_size) {
+ fprintf(stderr,
+ _("%s is capable of DAX but current block size "
+ "%u is different from system page size %u so "
+ "filesystem will not support DAX.\n"),
+ device_name, blocksize, sys_page_size);
+ }
}
#endif
return 0;
}
-static void check_fsck_needed(ext2_filsys fs, const char *prompt)
+static int check_fsck_needed(ext2_filsys fs, const char *prompt)
{
/* Refuse to modify anything but a freshly checked valid filesystem. */
if (!(fs->super->s_state & EXT2_VALID_FS) ||
puts(_(please_fsck));
if (mount_flags & EXT2_MF_READONLY)
printf("%s", _("(and reboot afterwards!)\n"));
- exit(1);
+ return 1;
}
/* Give the admin a few seconds to bail out of a dangerous op. */
if (!getenv("TUNE2FS_FORCE_PROMPT") && (!isatty(0) || !isatty(1)))
- return;
+ return 0;
puts(prompt);
proceed_question(5);
+
+ return 0;
}
static void request_dir_fsck_afterwards(ext2_filsys fs)
if (FEATURE_ON(E2P_FEATURE_RO_INCOMPAT,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
- check_fsck_needed(fs,
- _("Enabling checksums could take some time."));
+ if (check_fsck_needed(fs,
+ _("Enabling checksums could take some time.")))
+ return 1;
if (mount_flags & EXT2_MF_MOUNTED) {
fputs(_("Cannot enable metadata_csum on a mounted "
"filesystem!\n"), stderr);
- exit(1);
+ return 1;
}
if (!ext2fs_has_feature_extents(fs->super))
printf("%s",
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
__u32 test_features[3];
- check_fsck_needed(fs,
- _("Disabling checksums could take some time."));
+ if (check_fsck_needed(fs,
+ _("Disabling checksums could take some time.")))
+ return 1;
if (mount_flags & EXT2_MF_MOUNTED) {
fputs(_("Cannot disable metadata_csum on a mounted "
"filesystem!\n"), stderr);
- exit(1);
+ return 1;
}
rewrite_checksums = REWRITE_ALL;
if (mount_flags & EXT2_MF_MOUNTED) {
fputs(_("Cannot enable uninit_bg on a mounted "
"filesystem!\n"), stderr);
- exit(1);
+ return 1;
}
/* Do not enable uninit_bg when metadata_csum enabled */
if (mount_flags & EXT2_MF_MOUNTED) {
fputs(_("Cannot disable uninit_bg on a mounted "
"filesystem!\n"), stderr);
- exit(1);
+ return 1;
}
err = disable_uninit_bg(fs,
if (mount_flags & EXT2_MF_MOUNTED) {
fprintf(stderr, _("Cannot enable 64-bit mode "
"while mounted!\n"));
- exit(1);
+ return 1;
}
ext2fs_clear_feature_64bit(sb);
feature_64bit = 1;
if (mount_flags & EXT2_MF_MOUNTED) {
fprintf(stderr, _("Cannot disable 64-bit mode "
"while mounted!\n"));
- exit(1);
+ return 1;
}
ext2fs_set_feature_64bit(sb);
feature_64bit = -1;
if (fs->super->s_inode_size == EXT2_GOOD_OLD_INODE_SIZE) {
fprintf(stderr, _("Cannot enable project feature; "
"inode size too small.\n"));
- exit(1);
+ return 1;
}
Q_flag = 1;
quota_enable[PRJQUOTA] = QOPT_ENABLE;
stderr);
return 1;
}
- check_fsck_needed(fs, _("Recalculating checksums "
- "could take some time."));
+ if (check_fsck_needed(fs, _("Recalculating checksums "
+ "could take some time.")))
+ return 1;
rewrite_checksums = REWRITE_ALL;
}
}
return 1;
}
-static void handle_quota_options(ext2_filsys fs)
+static int handle_quota_options(ext2_filsys fs)
{
errcode_t retval;
quota_ctx_t qctx;
break;
if (qtype == MAXQUOTAS)
/* Nothing to do. */
- return;
+ return 0;
if (quota_enable[PRJQUOTA] == QOPT_ENABLE &&
fs->super->s_inode_size == EXT2_GOOD_OLD_INODE_SIZE) {
fprintf(stderr, _("Cannot enable project quota; "
"inode size too small.\n"));
- exit(1);
+ return 1;
}
for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
if (retval) {
com_err(program_name, retval,
_("while initializing quota context in support library"));
- exit(1);
+ return 1;
}
if (qtype_bits)
com_err(program_name, retval,
_("while updating quota limits (%d)"),
qtype);
- exit(1);
+ return 1;
}
}
retval = quota_write_inode(qctx, 1 << qtype);
com_err(program_name, retval,
_("while writing quota file (%d)"),
qtype);
- exit(1);
+ return 1;
}
/* Enable Quota feature if one of quota enabled */
if (!ext2fs_has_feature_quota(fs->super)) {
com_err(program_name, retval,
_("while removing quota file (%d)"),
qtype);
- exit(1);
+ return 1;
}
if (qtype == PRJQUOTA) {
ext2fs_clear_feature_project(fs->super);
}
if (need_dirty)
ext2fs_mark_super_dirty(fs);
- return;
+ return 0;
}
static int option_handle_function(char *token)
rc = 1;
goto closefs;
}
- check_fsck_needed(fs,
+ rc = check_fsck_needed(fs,
_("Resizing inodes could take some time."));
+ if (rc)
+ goto closefs;
/*
* If inode resize is requested use the
* Undo I/O manager
/* Recover the journal if possible. */
if ((open_flag & EXT2_FLAG_RW) && !(mount_flags & (EXT2_MF_BUSY | EXT2_MF_MOUNTED)) &&
ext2fs_has_feature_journal_needs_recovery(fs->super)) {
- errcode_t err;
-
printf(_("Recovering journal.\n"));
- err = ext2fs_run_ext3_journal(&fs);
- if (err) {
- com_err("tune2fs", err, "while recovering journal.\n");
+ retval = ext2fs_run_ext3_journal(&fs);
+ if (retval) {
+ com_err("tune2fs", retval,
+ "while recovering journal.\n");
printf(_("Please run e2fsck -fy %s.\n"), argv[1]);
if (fs)
ext2fs_close_free(&fs);
- exit(1);
+ rc = 1;
+ goto closefs;
}
sb = fs->super;
}
fputs(_("Warning: label too long, truncating.\n"),
stderr);
memset(sb->s_volume_name, 0, sizeof(sb->s_volume_name));
- strncpy(sb->s_volume_name, new_label,
+ strncpy((char *)sb->s_volume_name, new_label,
sizeof(sb->s_volume_name));
ext2fs_mark_super_dirty(fs);
}
if (M_flag) {
memset(sb->s_last_mounted, 0, sizeof(sb->s_last_mounted));
- strncpy(sb->s_last_mounted, new_last_mounted,
+ strncpy((char *)sb->s_last_mounted, new_last_mounted,
sizeof(sb->s_last_mounted));
ext2fs_mark_super_dirty(fs);
}
rc = 1;
goto closefs;
}
- handle_quota_options(fs);
+ rc = handle_quota_options(fs);
+ if (rc)
+ goto closefs;
}
if (U_flag) {
if (!ext2fs_has_feature_csum_seed(fs->super) &&
(ext2fs_has_feature_metadata_csum(fs->super) ||
ext2fs_has_feature_ea_inode(fs->super))) {
- check_fsck_needed(fs,
+ rc = check_fsck_needed(fs,
_("Setting the UUID on this "
"filesystem could take some time."));
+ if (rc)
+ goto closefs;
rewrite_checksums = REWRITE_ALL;
}
"metadata_csum_seed' and re-run this "
"command.\n"), stderr);
try_confirm_csum_seed_support();
- exit(1);
+ rc = 1;
+ goto closefs;
}
/*
resize2fs test
-debugfs -R ''stat file'' test.img 2>&1 | grep ''^Inode\|in inode body\|user.name (''
+debugfs -R ''stat file'' test.img 2>&1 | grep -E ''^Inode\|in inode body\|user.name \(''
Inode: 1550 Type: regular Mode: 0644 Flags: 0x0
user.name (11) = "propervalue"
Exit status is 0
The filesystem on test.img is now 5120 (1k) blocks long.
Exit status is 0
-debugfs -R ''stat file'' test.img 2>&1 | grep ''^Inode\|in inode body\|user.name (''
+debugfs -R ''stat file'' test.img 2>&1 | grep -E ''^Inode\|in inode body\|user.name \(''
Inode: 12 Type: regular Mode: 0644 Flags: 0x0
user.name (11) = "propervalue"
Exit status is 0
echo "resize2fs test" > $OUT.new
# Look at existing inline extended attribute
-echo "debugfs -R ''stat file'' test.img 2>&1 | grep ''^Inode\|in inode body\|user.name (''" >> $OUT.new
-$DEBUGFS -R "stat file" $TMPFILE 2>&1 | grep "^Inode\|in inode body\|user.name (" >> $OUT.new
+echo "debugfs -R ''stat file'' test.img 2>&1 | grep -E ''^Inode\|in inode body\|user.name \\(''" >> $OUT.new
+$DEBUGFS -R "stat file" $TMPFILE 2>&1 | grep -E "^Inode|in inode body|user.name \(" >> $OUT.new
status=$?
echo Exit status is $status >> $OUT.new
echo Exit status is $status >> $OUT.new
# Look at inline extended attribute in resized fs
-echo "debugfs -R ''stat file'' test.img 2>&1 | grep ''^Inode\|in inode body\|user.name (''" >> $OUT.new
-$DEBUGFS -R "stat file" $TMPFILE 2>&1 | grep "^Inode\|in inode body\|user.name (" >> $OUT.new
+echo "debugfs -R ''stat file'' test.img 2>&1 | grep -E ''^Inode\|in inode body\|user.name \\(''" >> $OUT.new
+$DEBUGFS -R "stat file" $TMPFILE 2>&1 | grep -E "^Inode|in inode body|user.name \(" >> $OUT.new
status=$?
echo Exit status is $status >> $OUT.new
return $status
fi
-$TUNE2FS -O ^mmp $TMPFILE > $test_name.log 2>&1
+$TUNE2FS -O ^mmp $TMPFILE >> $test_name.log 2>&1
status=$?
if [ "$status" != 0 ] ; then
echo "tune2fs -O ^mmp failed" > $test_name.failed
return $status
fi
-$FSCK $FSCK_OPT $TMPFILE > $test_name.log 2>&1
+$FSCK $FSCK_OPT $TMPFILE >> $test_name.log 2>&1
status=$?
if [ "$status" = 0 ] ; then
echo "$test_name: $test_description: ok"
--- /dev/null
+error running tune2fs with MMP
--- /dev/null
+FSCK_OPT=-yf
+
+$MKE2FS -q -F -o Linux -I 128 -b 1024 -O mmp $TMPFILE 100 > $test_name.log 2>&1
+status=$?
+if [ "$status" != 0 ] ; then
+ echo "mke2fs -O mmp failed" > $test_name.failed
+ echo "$test_name: $test_description: failed"
+ return $status
+fi
+
+$TUNE2FS -O project $TMPFILE >> $test_name.log 2>&1
+status=$?
+if [ "$status" == 0 ] ; then
+ echo "'tune2fs -O project' succeeded on small inode" > $test_name.failed
+ echo "$test_name: $test_description: failed"
+ return 1
+fi
+$TUNE2FS -o bad_option $TMPFILE >> $test_name.log 2>&1
+status=$?
+if [ "$status" == 0 ] ; then
+ echo "'tune2fs -o bad_option' succeeded" > $test_name.failed
+ echo "$test_name: $test_description: failed"
+ return 1
+fi
+$E2MMPSTATUS -i $TMPFILE >> $test_name.log 2>&1
+$E2MMPSTATUS $TMPFILE >> $test_name.log 2>&1
+status=$?
+if [ "$status" != 0 ] ; then
+ echo "$TUNE2FS left MMP block in bad state" > $test_name.failed
+ echo "$test_name: $test_description: failed"
+ return $status
+fi
+
+$FSCK $FSCK_OPT $TMPFILE >> $test_name.log 2>&1
+status=$?
+if [ "$status" = 0 ] ; then
+ echo "$test_name: $test_description: ok"
+ touch $test_name.ok
+else
+ echo "e2fsck after MMP disable failed" > $test_name.failed
+ echo "$test_name: $test_description: failed"
+ return $status
+fi
+rm -f $TMPFILE