summaryrefslogtreecommitdiffstats
path: root/debugfs/set_fields.c
diff options
context:
space:
mode:
Diffstat (limited to 'debugfs/set_fields.c')
-rw-r--r--debugfs/set_fields.c97
1 files changed, 69 insertions, 28 deletions
diff --git a/debugfs/set_fields.c b/debugfs/set_fields.c
index f916dea..bfe8a13 100644
--- a/debugfs/set_fields.c
+++ b/debugfs/set_fields.c
@@ -71,7 +71,9 @@ static errcode_t parse_string(struct field_set_info *info, char *field, char *ar
static errcode_t parse_uuid(struct field_set_info *info, char *field, char *arg);
static errcode_t parse_hashalg(struct field_set_info *info, char *field, char *arg);
static errcode_t parse_encoding(struct field_set_info *info, char *field, char *arg);
-static errcode_t parse_time(struct field_set_info *info, char *field, char *arg);
+static errcode_t parse_sb_time(struct field_set_info *info, char *field, char *arg);
+static errcode_t parse_ino_time(struct field_set_info *info, char *field, char *arg);
+
static errcode_t parse_bmap(struct field_set_info *info, char *field, char *arg);
static errcode_t parse_gd_csum(struct field_set_info *info, char *field, char *arg);
static errcode_t parse_inode_csum(struct field_set_info *info, char *field,
@@ -99,15 +101,16 @@ static struct field_set_info super_fields[] = {
{ "blocks_per_group", &set_sb.s_blocks_per_group, NULL, 4, parse_uint },
{ "clusters_per_group", &set_sb.s_clusters_per_group, NULL, 4, parse_uint },
{ "inodes_per_group", &set_sb.s_inodes_per_group, NULL, 4, parse_uint },
- { "mtime", &set_sb.s_mtime, NULL, 4, parse_time },
- { "wtime", &set_sb.s_wtime, NULL, 4, parse_time },
+ { "mtime", &set_sb.s_mtime, &set_sb.s_mtime_hi, 5, parse_sb_time },
+ { "wtime", &set_sb.s_wtime, &set_sb.s_wtime_hi, 5, parse_sb_time },
{ "mnt_count", &set_sb.s_mnt_count, NULL, 2, parse_uint },
{ "max_mnt_count", &set_sb.s_max_mnt_count, NULL, 2, parse_int },
/* s_magic */
{ "state", &set_sb.s_state, NULL, 2, parse_uint },
{ "errors", &set_sb.s_errors, NULL, 2, parse_uint },
{ "minor_rev_level", &set_sb.s_minor_rev_level, NULL, 2, parse_uint },
- { "lastcheck", &set_sb.s_lastcheck, NULL, 4, parse_time },
+ { "lastcheck", &set_sb.s_lastcheck, &set_sb.s_lastcheck_hi, 5,
+ parse_sb_time },
{ "checkinterval", &set_sb.s_checkinterval, NULL, 4, parse_uint },
{ "creator_os", &set_sb.s_creator_os, NULL, 4, parse_uint },
{ "rev_level", &set_sb.s_rev_level, NULL, 4, parse_uint },
@@ -139,7 +142,8 @@ static struct field_set_info super_fields[] = {
{ "desc_size", &set_sb.s_desc_size, NULL, 2, parse_uint },
{ "default_mount_opts", &set_sb.s_default_mount_opts, NULL, 4, parse_uint },
{ "first_meta_bg", &set_sb.s_first_meta_bg, NULL, 4, parse_uint },
- { "mkfs_time", &set_sb.s_mkfs_time, NULL, 4, parse_time },
+ { "mkfs_time", &set_sb.s_mkfs_time, &set_sb.s_mkfs_time_hi, 5,
+ parse_sb_time },
{ "jnl_blocks", &set_sb.s_jnl_blocks[0], NULL, 4, parse_uint, FLAG_ARRAY,
17 },
{ "min_extra_isize", &set_sb.s_min_extra_isize, NULL, 2, parse_uint },
@@ -167,12 +171,14 @@ static struct field_set_info super_fields[] = {
{ "checksum_type", &set_sb.s_checksum_type, NULL, 1, parse_uint },
{ "encryption_level", &set_sb.s_encryption_level, NULL, 1, parse_uint },
{ "error_count", &set_sb.s_error_count, NULL, 4, parse_uint },
- { "first_error_time", &set_sb.s_first_error_time, NULL, 4, parse_time },
+ { "first_error_time", &set_sb.s_first_error_time,
+ &set_sb.s_first_error_time_hi, 5, parse_sb_time },
{ "first_error_ino", &set_sb.s_first_error_ino, NULL, 4, parse_uint },
{ "first_error_block", &set_sb.s_first_error_block, NULL, 8, parse_uint },
{ "first_error_func", &set_sb.s_first_error_func, NULL, 32, parse_string },
{ "first_error_line", &set_sb.s_first_error_line, NULL, 4, parse_uint },
- { "last_error_time", &set_sb.s_last_error_time, NULL, 4, parse_time },
+ { "last_error_time", &set_sb.s_last_error_time,
+ &set_sb.s_last_error_time_hi, 5, parse_sb_time },
{ "last_error_ino", &set_sb.s_last_error_ino, NULL, 4, parse_uint },
{ "last_error_block", &set_sb.s_last_error_block, NULL, 8, parse_uint },
{ "last_error_func", &set_sb.s_last_error_func, NULL, 32, parse_string },
@@ -193,13 +199,13 @@ static struct field_set_info inode_fields[] = {
2, parse_uint },
{ "size", &set_inode.i_size, &set_inode.i_size_high, 4, parse_uint },
{ "atime", &set_inode.i_atime, &set_inode.i_atime_extra,
- 4, parse_time },
+ 4, parse_ino_time },
{ "ctime", &set_inode.i_ctime, &set_inode.i_ctime_extra,
- 4, parse_time },
+ 4, parse_ino_time },
{ "mtime", &set_inode.i_mtime, &set_inode.i_mtime_extra,
- 4, parse_time },
+ 4, parse_ino_time },
{ "dtime", &set_inode.i_dtime, NULL,
- 4, parse_time },
+ 4, parse_ino_time },
{ "gid", &set_inode.i_gid, &set_inode.osd2.linux2.l_i_gid_high,
2, parse_uint },
{ "links_count", &set_inode.i_links_count, NULL, 2, parse_uint },
@@ -236,7 +242,7 @@ static struct field_set_info inode_fields[] = {
{ "atime_extra", &set_inode.i_atime_extra, NULL,
4, parse_uint, FLAG_ALIAS },
{ "crtime", &set_inode.i_crtime, &set_inode.i_crtime_extra,
- 4, parse_time },
+ 4, parse_ino_time },
{ "crtime_extra", &set_inode.i_crtime_extra, NULL,
4, parse_uint, FLAG_ALIAS },
{ "projid", &set_inode.i_projid, NULL, 4, parse_uint },
@@ -441,6 +447,9 @@ static struct field_set_info *find_field(struct field_set_info *fields,
* Note: info->size == 6 is special; this means a base size 4 bytes,
* and secondary (high) size of 2 bytes. This is needed for the
* special case of i_blocks_high and i_file_acl_high.
+ *
+ * Similarly, info->size == 5 is for superblock timestamps, which have
+ * a 4-byte primary field and a 1-byte _hi field.
*/
static errcode_t parse_uint(struct field_set_info *info, char *field,
char *arg)
@@ -449,7 +458,8 @@ static errcode_t parse_uint(struct field_set_info *info, char *field,
int suffix = check_suffix(field);
char *tmp;
void *field1 = info->ptr, *field2 = info->ptr2;
- int size = (info->size == 6) ? 4 : info->size;
+ unsigned int size = (info->size == 6 || info->size == 5) ? 4 :
+ info->size;
union {
__u64 *ptr64;
__u32 *ptr32;
@@ -477,7 +487,7 @@ static errcode_t parse_uint(struct field_set_info *info, char *field,
}
mask = ~0ULL >> ((8 - size) * 8);
limit = ~0ULL >> ((8 - info->size) * 8);
- if (field2 && info->size != 6)
+ if (field2 && (info->size != 6 && info->size != 5))
limit = ~0ULL >> ((8 - info->size*2) * 8);
if (num > limit) {
@@ -504,13 +514,14 @@ static errcode_t parse_uint(struct field_set_info *info, char *field,
return 0;
n = (size == 8) ? 0 : (num >> (size*8));
u.ptr8 = (__u8 *) field2;
- if (info->size == 6)
- size = 2;
+ if (info->size > size)
+ size = info->size - size;
switch (size) {
case 8:
/* Should never get here */
- fprintf(stderr, "64-bit field %s has a second 64-bit field\n"
- "defined; BUG?!?\n", info->name);
+ fprintf(stderr,
+ "64-bit field %s has a second 64-bit field defined; BUG?!?\n",
+ info->name);
*u.ptr64 = 0;
break;
case 4:
@@ -572,18 +583,19 @@ static errcode_t parse_string(struct field_set_info *info,
return 0;
}
-static errcode_t parse_time(struct field_set_info *info,
- char *field, char *arg)
+static errcode_t parse_sb_time(struct field_set_info *info,
+ char *field, char *arg)
{
__s64 t;
__u32 t_low, t_high;
- __u32 *ptr_low, *ptr_high;
+ __u32 *ptr_low;
+ __u8 *ptr_high;
if (check_suffix(field))
return parse_uint(info, field, arg);
ptr_low = (__u32 *) info->ptr;
- ptr_high = (__u32 *) info->ptr2;
+ ptr_high = (__u8 *) info->ptr2;
t = string_to_time(arg);
@@ -600,6 +612,34 @@ static errcode_t parse_time(struct field_set_info *info,
return 0;
}
+static errcode_t parse_ino_time(struct field_set_info *info,
+ char *field, char *arg)
+{
+ __s64 t;
+ __u32 t_low, t_high;
+ __u32 *ptr_low, *ptr_high;
+
+ if (check_suffix(field))
+ return parse_uint(info, field, arg);
+
+ ptr_low = (__u32 *) info->ptr;
+ ptr_high = (__u32 *) info->ptr2;
+
+ t = string_to_time(arg);
+
+ if (t == -1) {
+ fprintf(stderr, "Couldn't parse '%s' for field %s.\n",
+ arg, info->name);
+ return EINVAL;
+ }
+ t_low = (__u32) t;
+ t_high = __encode_extra_time(t, 0);
+ *ptr_low = t_low;
+ if (ptr_high)
+ *ptr_high = t_high;
+ return 0;
+}
+
static errcode_t parse_uuid(struct field_set_info *info,
char *field EXT2FS_ATTR((unused)), char *arg)
{
@@ -781,7 +821,8 @@ static void print_possible_fields(struct field_set_info *fields)
type = "UUID";
else if (ss->func == parse_hashalg)
type = "hash algorithm";
- else if (ss->func == parse_time)
+ else if ((ss->func == parse_sb_time) ||
+ (ss->func == parse_ino_time))
type = "date/time";
else if (ss->func == parse_bmap)
type = "set physical->logical block map";
@@ -803,7 +844,7 @@ static void print_possible_fields(struct field_set_info *fields)
}
-void do_set_super(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
+void do_set_super(int argc, ss_argv_t argv, int sci_idx EXT2FS_ATTR((unused)),
void *infop EXT2FS_ATTR((unused)))
{
const char *usage = "<field> <value>\n"
@@ -831,7 +872,7 @@ void do_set_super(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
}
}
-void do_set_inode(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
+void do_set_inode(int argc, ss_argv_t argv, int sci_idx EXT2FS_ATTR((unused)),
void *infop EXT2FS_ATTR((unused)))
{
const char *usage = "<inode> <field> <value>\n"
@@ -873,7 +914,7 @@ void do_set_inode(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
}
}
-void do_set_block_group_descriptor(int argc, char *argv[],
+void do_set_block_group_descriptor(int argc, ss_argv_t argv,
int sci_idx EXT2FS_ATTR((unused)),
void *infop EXT2FS_ATTR((unused)))
{
@@ -953,7 +994,7 @@ static errcode_t parse_mmp_clear(struct field_set_info *info,
}
#ifdef CONFIG_MMP
-void do_set_mmp_value(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
+void do_set_mmp_value(int argc, ss_argv_t argv, int sci_idx EXT2FS_ATTR((unused)),
void *infop EXT2FS_ATTR((unused)))
{
const char *usage = "<field> <value>\n"
@@ -1013,7 +1054,7 @@ void do_set_mmp_value(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
}
#else
void do_set_mmp_value(int argc EXT2FS_ATTR((unused)),
- char *argv[] EXT2FS_ATTR((unused)),
+ ss_argv_t argv EXT2FS_ATTR((unused)),
int sci_idx EXT2FS_ATTR((unused)),
void *infop EXT2FS_ATTR((unused)))
{