}
/*
+ * 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.
*/
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++;
}
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++;
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 */