return;
}
- if (debugfs_read_inode_full(inode, inode_buf, argv[0],
- EXT2_INODE_SIZE(current_fs->super))) {
+ if (debugfs_read_inode2(inode, inode_buf, argv[0],
+ EXT2_INODE_SIZE(current_fs->super), 0)) {
free(inode_buf);
return;
}
if (!dest_ino)
return;
- if (debugfs_read_inode_full(src_ino, (struct ext2_inode *) buf,
- argv[0], sizeof(buf)))
+ if (debugfs_read_inode2(src_ino, (struct ext2_inode *) buf,
+ argv[0], sizeof(buf), 0))
return;
- if (debugfs_write_inode_full(dest_ino, (struct ext2_inode *) buf,
- argv[0], sizeof(buf)))
+ if (debugfs_write_inode2(dest_ino, (struct ext2_inode *) buf,
+ argv[0], sizeof(buf), 0))
return;
}
blk64_t *block, blk64_t *count);
extern int debugfs_read_inode(ext2_ino_t ino, struct ext2_inode * inode,
const char *cmd);
-extern int debugfs_read_inode_full(ext2_ino_t ino, struct ext2_inode * inode,
- const char *cmd, int bufsize);
+extern int debugfs_read_inode2(ext2_ino_t ino, struct ext2_inode * inode,
+ const char *cmd, int bufsize, int flags);
extern int debugfs_write_inode(ext2_ino_t ino, struct ext2_inode * inode,
const char *cmd);
-extern int debugfs_write_inode_full(ext2_ino_t ino, struct ext2_inode * inode,
- const char *cmd, int bufsize);
+extern int debugfs_write_inode2(ext2_ino_t ino, struct ext2_inode * inode,
+ const char *cmd, int bufsize, int flags);
extern int debugfs_write_new_inode(ext2_ino_t ino, struct ext2_inode * inode,
const char *cmd);
extern int ext2_file_type(unsigned int mode);
#define FLAG_ARRAY 0x0001
#define FLAG_ALIAS 0x0002 /* Data intersects with other field */
+#define FLAG_CSUM 0x0004
struct field_set_info {
const char *name;
static errcode_t parse_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,
+ char *arg);
static errcode_t parse_mmp_clear(struct field_set_info *info, char *field,
char *arg);
{ "frag", &set_inode.osd2.hurd2.h_i_frag, NULL, 1, parse_uint, FLAG_ALIAS },
{ "fsize", &set_inode.osd2.hurd2.h_i_fsize, NULL, 1, parse_uint },
{ "checksum", &set_inode.osd2.linux2.l_i_checksum_lo,
- &set_inode.i_checksum_hi, 2, parse_uint },
+ &set_inode.i_checksum_hi, 2, parse_inode_csum, FLAG_CSUM },
{ "author", &set_inode.osd2.hurd2.h_i_author, NULL,
4, parse_uint, FLAG_ALIAS },
{ "extra_isize", &set_inode.i_extra_isize, NULL,
return parse_uint(info, field, arg);
}
+static errcode_t parse_inode_csum(struct field_set_info *info, char *field,
+ char *arg)
+{
+ errcode_t retval = 0;
+ __u32 crc;
+ int is_large_inode = 0;
+ struct ext2_inode_large *tmp_inode;
+
+ if (strcmp(arg, "calc") == 0) {
+ size_t sz = EXT2_INODE_SIZE(current_fs->super);
+ struct ext2_inode_large *tmp_inode = NULL;
+
+ retval = ext2fs_get_mem(sz, &tmp_inode);
+ if (retval)
+ goto out;
+
+ retval = ext2fs_read_inode_full(current_fs, set_ino,
+ (struct ext2_inode *) tmp_inode,
+ sz);
+ if (retval)
+ goto out;
+
+#ifdef WORDS_BIGENDIAN
+ ext2fs_swap_inode_full(current_fs, tmp_inode,
+ tmp_inode, 1, sz);
+#endif
+
+ if (sz > EXT2_GOOD_OLD_INODE_SIZE)
+ is_large_inode = 1;
+
+ retval = ext2fs_inode_csum_set(current_fs, set_ino,
+ tmp_inode);
+ if (retval)
+ goto out;
+#ifdef WORDS_BIGENDIAN
+ crc = set_inode.i_checksum_lo =
+ ext2fs_swab16(tmp_inode->i_checksum_lo);
+
+#else
+ crc = set_inode.i_checksum_lo = tmp_inode->i_checksum_lo;
+#endif
+ if (is_large_inode &&
+ set_inode.i_extra_isize >=
+ (offsetof(struct ext2_inode_large,
+ i_checksum_hi) -
+ EXT2_GOOD_OLD_INODE_SIZE)) {
+#ifdef WORDS_BIGENDIAN
+ set_inode.i_checksum_lo =
+ ext2fs_swab16(tmp_inode->i_checksum_lo);
+#else
+ set_inode.i_checksum_hi = tmp_inode->i_checksum_hi;
+#endif
+ crc |= ((__u32)set_inode.i_checksum_hi) << 16;
+ }
+ printf("Checksum set to 0x%08x\n", crc);
+ out:
+ ext2fs_free_mem(&tmp_inode);
+ return retval;
+ }
+ return parse_uint(info, field, arg);
+}
+
static void print_possible_fields(struct field_set_info *fields)
{
struct field_set_info *ss;
if (!set_ino)
return;
- if (debugfs_read_inode_full(set_ino,
- (struct ext2_inode *) &set_inode, argv[1],
- sizeof(set_inode)))
+ if (debugfs_read_inode2(set_ino,
+ (struct ext2_inode *) &set_inode, argv[1],
+ sizeof(set_inode),
+ (ss->flags & FLAG_CSUM) ?
+ READ_INODE_NOCSUM : 0))
return;
if (ss->func(ss, argv[2], argv[3]) == 0) {
- if (debugfs_write_inode_full(set_ino,
- (struct ext2_inode *) &set_inode,
- argv[1], sizeof(set_inode)))
- return;
+ debugfs_write_inode2(set_ino,
+ (struct ext2_inode *) &set_inode,
+ argv[1], sizeof(set_inode),
+ (ss->flags & FLAG_CSUM) ?
+ WRITE_INODE_NOCSUM : 0);
}
}
return 0;
}
-int debugfs_read_inode_full(ext2_ino_t ino, struct ext2_inode * inode,
- const char *cmd, int bufsize)
+int debugfs_read_inode2(ext2_ino_t ino, struct ext2_inode * inode,
+ const char *cmd, int bufsize, int flags)
{
int retval;
- retval = ext2fs_read_inode_full(current_fs, ino, inode, bufsize);
+ retval = ext2fs_read_inode2(current_fs, ino, inode, bufsize, flags);
if (retval) {
com_err(cmd, retval, "while reading inode %u", ino);
return 1;
return 0;
}
-int debugfs_write_inode_full(ext2_ino_t ino,
- struct ext2_inode *inode,
- const char *cmd,
- int bufsize)
+int debugfs_write_inode2(ext2_ino_t ino,
+ struct ext2_inode *inode,
+ const char *cmd,
+ int bufsize, int flags)
{
int retval;
- retval = ext2fs_write_inode_full(current_fs, ino,
- inode, bufsize);
+ retval = ext2fs_write_inode2(current_fs, ino, inode, bufsize, flags);
if (retval) {
com_err(cmd, retval, "while writing inode %u", ino);
return 1;