e2fsck: clear extents and inline_data flags from fifo/socket/device inodes

Since fifo, socket, and device inodes cannot have inline data or
extents, strip off these flags if we find them.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
crypto
Darrick J. Wong 2014-08-10 18:41:07 -04:00 committed by Theodore Ts'o
parent 2ece839011
commit 8dae07fb55
4 changed files with 34 additions and 0 deletions

View File

@ -271,6 +271,24 @@ exit_inline:
return 1;
}
/*
* If the extents or inlinedata flags are set on the inode, offer to clear 'em.
*/
#define BAD_SPECIAL_FLAGS (EXT4_EXTENTS_FL | EXT4_INLINE_DATA_FL)
static void check_extents_inlinedata(e2fsck_t ctx,
struct problem_context *pctx)
{
if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
return;
if (!fix_problem(ctx, PR_1_SPECIAL_EXTENTS_IDATA, pctx))
return;
pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
}
#undef BAD_SPECIAL_FLAGS
/*
* If the immutable (or append-only) flag is set on the inode, offer
* to clear it.
@ -1420,11 +1438,13 @@ void e2fsck_pass1(e2fsck_t ctx)
ctx->fs_regular_count++;
} else if (LINUX_S_ISCHR (inode->i_mode) &&
e2fsck_pass1_check_device_inode(fs, inode)) {
check_extents_inlinedata(ctx, &pctx);
check_immutable(ctx, &pctx);
check_size(ctx, &pctx);
ctx->fs_chardev_count++;
} else if (LINUX_S_ISBLK (inode->i_mode) &&
e2fsck_pass1_check_device_inode(fs, inode)) {
check_extents_inlinedata(ctx, &pctx);
check_immutable(ctx, &pctx);
check_size(ctx, &pctx);
ctx->fs_blockdev_count++;
@ -1445,11 +1465,13 @@ void e2fsck_pass1(e2fsck_t ctx)
}
else if (LINUX_S_ISFIFO (inode->i_mode) &&
e2fsck_pass1_check_device_inode(fs, inode)) {
check_extents_inlinedata(ctx, &pctx);
check_immutable(ctx, &pctx);
check_size(ctx, &pctx);
ctx->fs_fifo_count++;
} else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
e2fsck_pass1_check_device_inode(fs, inode)) {
check_extents_inlinedata(ctx, &pctx);
check_immutable(ctx, &pctx);
check_size(ctx, &pctx);
ctx->fs_sockets_count++;

View File

@ -1050,6 +1050,12 @@ static struct e2fsck_problem problem_table[] = {
N_("@i %i has INLINE_DATA_FL flag but @a not found. "),
PROMPT_TRUNCATE, 0 },
/* Extents/inlinedata flag set on a device or socket inode */
{ PR_1_SPECIAL_EXTENTS_IDATA,
N_("Special (@v/socket/fifo) file (@i %i) has extents\n"
"or inline-data flag set. "),
PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
/* Pass 1b errors */
/* Pass 1B: Rescan for duplicate/bad blocks */

View File

@ -612,6 +612,9 @@ struct problem_context {
/* Inode has INLINE_DATA_FL flag but extended attribute not found */
#define PR_1_INLINE_DATA_NO_ATTR 0x010075
/* extents/inlinedata set on fifo/socket/device */
#define PR_1_SPECIAL_EXTENTS_IDATA 0x010076
/*
* Pass 1b errors
*/

View File

@ -22,6 +22,9 @@ Clear inode? yes
Inode 18, i_blocks is 2, should be 0. Fix? yes
Special (device/socket/fifo) file (inode 19) has extents
or inline-data flag set. Clear? yes
Pass 2: Checking directory structure
Entry 'fbad-flag' in / (2) has deleted/unused inode 18. Clear? yes