Fix e2fsck, debugfs, and the ext2fs_mkdir function so that when we create

a new inode we make sure that the extra information in the inode (any extra
fields in a large inode and any ea-in-inode information) is cleared.  This 
can happen when e2fsck creates a new root inode or a new lost+found directory,
or when the user uses the debugfs write, mknod, or mkdir commands.  Otherwise,
the newly create inode could inherit garbage (or old EA information) from
a previously deleted inode.
This commit is contained in:
Theodore Ts'o 2005-03-20 20:05:22 -05:00
parent ea822eeba3
commit 030970ed75
10 changed files with 65 additions and 5 deletions

View File

@ -1,5 +1,10 @@
2005-03-20 Theodore Ts'o <tytso@mit.edu> 2005-03-20 Theodore Ts'o <tytso@mit.edu>
* util.c (debugfs_write_new_inode): New function
* debgufs.c (do_write, do_mknod): Call ext2fs_write_new_inode()
instead of ext2fs_write_inode().
* debugfs.c (do_stat): Add support for dumping extended attributes * debugfs.c (do_stat): Add support for dumping extended attributes
which are stored in the inode body. which are stored in the inode body.

View File

@ -1294,7 +1294,7 @@ void do_write(int argc, char *argv[])
inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL); inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL);
inode.i_links_count = 1; inode.i_links_count = 1;
inode.i_size = statbuf.st_size; inode.i_size = statbuf.st_size;
if (debugfs_write_inode(newfile, &inode, argv[0])) { if (debugfs_write_new_inode(newfile, &inode, argv[0])) {
close(fd); close(fd);
return; return;
} }
@ -1387,7 +1387,7 @@ void do_mknod(int argc, char *argv[])
inode.i_block[1] = (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12); inode.i_block[1] = (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12);
} }
inode.i_links_count = 1; inode.i_links_count = 1;
if (debugfs_write_inode(newfile, &inode, argv[0])) if (debugfs_write_new_inode(newfile, &inode, argv[0]))
return; return;
} }

View File

@ -45,6 +45,8 @@ extern int debugfs_read_inode(ext2_ino_t ino, struct ext2_inode * inode,
const char *cmd); const char *cmd);
extern int debugfs_write_inode(ext2_ino_t ino, struct ext2_inode * inode, extern int debugfs_write_inode(ext2_ino_t ino, struct ext2_inode * inode,
const char *cmd); const char *cmd);
extern int debugfs_write_new_inode(ext2_ino_t ino, struct ext2_inode * inode,
const char *cmd);
/* ss command functions */ /* ss command functions */

View File

@ -346,3 +346,15 @@ int debugfs_write_inode(ext2_ino_t ino, struct ext2_inode * inode,
return 0; return 0;
} }
int debugfs_write_new_inode(ext2_ino_t ino, struct ext2_inode * inode,
const char *cmd)
{
int retval;
retval = ext2fs_write_new_inode(current_fs, ino, inode);
if (retval) {
com_err(cmd, retval, "while creating inode %u", ino);
return 1;
}
return 0;
}

View File

@ -1,5 +1,8 @@
2005-03-20 Theodore Ts'o <tytso@mit.edu> 2005-03-20 Theodore Ts'o <tytso@mit.edu>
* pass3.c (check_root, e2fsck_get_lost_and_found): Call
ext2fs_write_new_inode() instead of ext2fs_write_inode().
* pass1.c (check_blocks): Move counting the extended attribute * pass1.c (check_blocks): Move counting the extended attribute
block earlier so that we don't have to worry about block earlier so that we don't have to worry about
num_blocks wrapping for files which are too big. num_blocks wrapping for files which are too big.

View File

@ -230,7 +230,7 @@ static void check_root(e2fsck_t ctx)
/* /*
* Write out the inode. * Write out the inode.
*/ */
pctx.errcode = ext2fs_write_inode(fs, EXT2_ROOT_INO, &inode); pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
if (pctx.errcode) { if (pctx.errcode) {
pctx.str = "ext2fs_write_inode"; pctx.str = "ext2fs_write_inode";
fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx); fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
@ -478,7 +478,7 @@ ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
/* /*
* Next, write out the inode. * Next, write out the inode.
*/ */
pctx.errcode = ext2fs_write_inode(fs, ino, &inode); pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
if (pctx.errcode) { if (pctx.errcode) {
pctx.str = "ext2fs_write_inode"; pctx.str = "ext2fs_write_inode";
fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx); fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);

View File

@ -1,3 +1,13 @@
2005-03-20 Theodore Ts'o <tytso@mit.edu>
* mkdir.c (ext2fs_mkdir): Call ext2fs_write_new_inode() instead of
ext2fs_write_inode().
* inode.c (ext2fs_write_new_inode): New function which should be
used when the caller is writing an inode for the first
time. It makes sure that the extra portion of the large
inode is cleared.
2005-03-18 Theodore Ts'o <tytso@mit.edu> 2005-03-18 Theodore Ts'o <tytso@mit.edu>
* Makefile.in: Fix clean target to remove tst_getsectsize. * Makefile.in: Fix clean target to remove tst_getsectsize.

View File

@ -816,6 +816,8 @@ extern errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
int bufsize); int bufsize);
extern errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino, extern errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode * inode); struct ext2_inode * inode);
extern errcode_t ext2fs_write_new_inode(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode * inode);
extern errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks); extern errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks);
extern errcode_t ext2fs_check_directory(ext2_filsys fs, ext2_ino_t ino); extern errcode_t ext2fs_check_directory(ext2_filsys fs, ext2_ino_t ino);

View File

@ -715,6 +715,32 @@ errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino,
return ext2fs_write_inode_full(fs, ino, inode, return ext2fs_write_inode_full(fs, ino, inode,
sizeof(struct ext2_inode)); sizeof(struct ext2_inode));
} }
/*
* This function should be called when writing a new inode. It makes
* sure that extra part of large inodes is cleared.
*/
errcode_t ext2fs_write_new_inode(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode *inode)
{
struct ext2_inode *buf;
errcode_t retval;
int size = EXT2_INODE_SIZE(fs->super);
if (size == sizeof(struct ext2_inode))
return ext2fs_write_inode_full(fs, ino, inode,
sizeof(struct ext2_inode));
buf = malloc(size);
if (!buf)
return ENOMEM;
memset(buf, 0, size);
*buf = *inode;
retval = ext2fs_write_inode_full(fs, ino, buf, size);
}
errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks) errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks)
{ {

View File

@ -94,7 +94,7 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
retval = ext2fs_write_dir_block(fs, blk, block); retval = ext2fs_write_dir_block(fs, blk, block);
if (retval) if (retval)
goto cleanup; goto cleanup;
retval = ext2fs_write_inode(fs, ino, &inode); retval = ext2fs_write_new_inode(fs, ino, &inode);
if (retval) if (retval)
goto cleanup; goto cleanup;