aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis Henriques (SUSE) <luis.henriques@linux.dev>2024-04-05 15:24:02 +0100
committerTheodore Ts'o <tytso@mit.edu>2024-04-15 23:59:35 -0400
commiteb782652045e67a5379dd319613b0d3d924901dd (patch)
tree3d75addc5f9c2e1e1d52d69a695f93a0f81440ff
parent87cbb381f2e2fb9aab316187a70acca9f6d5061b (diff)
downloade2fsprogs-eb782652045e67a5379dd319613b0d3d924901dd.tar.gz
e2fsck: update quota accounting after directory optimization
In "Pass 3A: Optimizing directories", a directory may have it's size reduced. If that happens and quota is enabled in the filesystem, the quota information will be incorrect because it doesn't take the rehash into account. This issue was detected by running fstest ext4/014. This patch simply updates the quota data accordingly, after the directory is written and it's size has been updated. Link: https://bugzilla.kernel.org/show_bug.cgi?id=218626 Signed-off-by: Luis Henriques (SUSE) <luis.henriques@linux.dev> Reviewed-by: Andreas Dilger <adilger@dilger.ca> Link: https://lore.kernel.org/r/20240405142405.12312-2-luis.henriques@linux.dev Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r--e2fsck/rehash.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/e2fsck/rehash.c b/e2fsck/rehash.c
index c1da7d527..4847d172e 100644
--- a/e2fsck/rehash.c
+++ b/e2fsck/rehash.c
@@ -987,14 +987,18 @@ errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino,
{
ext2_filsys fs = ctx->fs;
errcode_t retval;
- struct ext2_inode inode;
+ struct ext2_inode_large inode;
char *dir_buf = 0;
struct fill_dir_struct fd = { NULL, NULL, 0, 0, 0, NULL,
0, 0, 0, 0, 0, 0 };
struct out_dir outdir = { 0, 0, 0, 0 };
- struct name_cmp_ctx name_cmp_ctx = {0, NULL};
+ struct name_cmp_ctx name_cmp_ctx = {0, NULL};
+ __u64 osize;
- e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
+ e2fsck_read_inode_full(ctx, ino, EXT2_INODE(&inode),
+ sizeof(inode), "rehash_dir");
+
+ osize = EXT2_I_SIZE(&inode);
if (ext2fs_has_feature_inline_data(fs->super) &&
(inode.i_flags & EXT4_INLINE_DATA_FL))
@@ -1013,7 +1017,7 @@ errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino,
fd.ino = ino;
fd.ctx = ctx;
fd.buf = dir_buf;
- fd.inode = &inode;
+ fd.inode = EXT2_INODE(&inode);
fd.dir = ino;
if (!ext2fs_has_feature_dir_index(fs->super) ||
(inode.i_size / fs->blocksize) < 2)
@@ -1092,14 +1096,25 @@ resort:
goto errout;
}
- retval = write_directory(ctx, fs, &outdir, ino, &inode, fd.compress);
+ retval = write_directory(ctx, fs, &outdir, ino, EXT2_INODE(&inode),
+ fd.compress);
if (retval)
goto errout;
+ if ((osize > EXT2_I_SIZE(&inode)) &&
+ (ino != quota_type2inum(PRJQUOTA, fs->super)) &&
+ (ino != fs->super->s_orphan_file_inum) &&
+ (ino == EXT2_ROOT_INO || ino >= EXT2_FIRST_INODE(ctx->fs->super)) &&
+ !(inode.i_flags & EXT4_EA_INODE_FL)) {
+ quota_data_sub(ctx->qctx, &inode,
+ ino, osize - EXT2_I_SIZE(&inode));
+ }
+
if (ctx->options & E2F_OPT_CONVERT_BMAP)
retval = e2fsck_rebuild_extents_later(ctx, ino);
else
- retval = e2fsck_check_rebuild_extents(ctx, ino, &inode, pctx);
+ retval = e2fsck_check_rebuild_extents(ctx, ino,
+ EXT2_INODE(&inode), pctx);
errout:
ext2fs_free_mem(&dir_buf);
ext2fs_free_mem(&fd.harray);