]>
git.ipfire.org Git - thirdparty/e2fsprogs.git/blob - e2fsck/quota.c
2 * quota.c --- code for handling ext4 quota inodes
7 #ifdef HAVE_SYS_MOUNT_H
10 #define MNT_FL (MS_MGC_VAL | MS_RDONLY)
12 #ifdef HAVE_SYS_STAT_H
19 static errcode_t
move_quota_inode(ext2_filsys fs
, ext2_ino_t from_ino
,
20 ext2_ino_t to_ino
, enum quota_type qtype
)
22 struct ext2_inode inode
;
24 char qf_name
[QUOTA_NAME_LEN
];
26 /* We need the inode bitmap to be loaded */
27 retval
= ext2fs_read_bitmaps(fs
);
29 com_err("ext2fs_read_bitmaps", retval
, "%s",
30 _("in move_quota_inode"));
34 retval
= ext2fs_read_inode(fs
, from_ino
, &inode
);
36 com_err("ext2fs_read_inode", retval
, "%s",
37 _("in move_quota_inode"));
41 inode
.i_links_count
= 1;
42 inode
.i_mode
= LINUX_S_IFREG
| 0600;
43 inode
.i_flags
= EXT2_IMMUTABLE_FL
;
44 if (ext2fs_has_feature_extents(fs
->super
))
45 inode
.i_flags
|= EXT4_EXTENTS_FL
;
47 retval
= ext2fs_write_new_inode(fs
, to_ino
, &inode
);
49 com_err("ext2fs_write_new_inode", retval
, "%s",
50 _("in move_quota_inode"));
54 /* unlink the old inode */
55 quota_get_qf_name(qtype
, QFMT_VFS_V1
, qf_name
);
56 retval
= ext2fs_unlink(fs
, EXT2_ROOT_INO
, qf_name
, from_ino
, 0);
58 com_err("ext2fs_unlink", retval
, "%s",
59 _("in move_quota_inode"));
62 ext2fs_inode_alloc_stats(fs
, from_ino
, -1);
63 /* Clear out the original inode in the inode-table block. */
64 memset(&inode
, 0, sizeof(struct ext2_inode
));
65 ext2fs_write_inode(fs
, from_ino
, &inode
);
69 void e2fsck_hide_quota(e2fsck_t ctx
)
71 struct ext2_super_block
*sb
= ctx
->fs
->super
;
72 struct problem_context pctx
;
73 ext2_filsys fs
= ctx
->fs
;
74 enum quota_type qtype
;
77 clear_problem_context(&pctx
);
79 if ((ctx
->options
& E2F_OPT_READONLY
) ||
80 !ext2fs_has_feature_quota(sb
))
83 for (qtype
= 0; qtype
< MAXQUOTAS
; qtype
++) {
84 pctx
.dir
= 2; /* This is a guess, but it's a good one */
85 pctx
.ino
= *quota_sb_inump(sb
, qtype
);
87 quota_ino
= quota_type2inum(qtype
, fs
->super
);
88 if (pctx
.ino
&& (pctx
.ino
!= quota_ino
) &&
89 fix_problem(ctx
, PR_0_HIDE_QUOTA
, &pctx
)) {
90 if (move_quota_inode(fs
, pctx
.ino
, quota_ino
, qtype
))
92 *quota_sb_inump(sb
, qtype
) = quota_ino
;
93 ext2fs_mark_super_dirty(fs
);
100 void e2fsck_validate_quota_inodes(e2fsck_t ctx
)
102 struct ext2_super_block
*sb
= ctx
->fs
->super
;
103 struct problem_context pctx
;
104 ext2_filsys fs
= ctx
->fs
;
105 enum quota_type qtype
;
107 clear_problem_context(&pctx
);
109 for (qtype
= 0; qtype
< MAXQUOTAS
; qtype
++) {
110 pctx
.ino
= *quota_sb_inump(sb
, qtype
);
113 ((pctx
.ino
== EXT2_BAD_INO
) ||
114 (pctx
.ino
== EXT2_ROOT_INO
) ||
115 (pctx
.ino
== EXT2_BOOT_LOADER_INO
) ||
116 (pctx
.ino
== EXT2_UNDEL_DIR_INO
) ||
117 (pctx
.ino
== EXT2_RESIZE_INO
) ||
118 (pctx
.ino
== EXT2_JOURNAL_INO
) ||
119 (pctx
.ino
== EXT2_EXCLUDE_INO
) ||
120 (pctx
.ino
== EXT4_REPLICA_INO
) ||
121 (pctx
.ino
> fs
->super
->s_inodes_count
)) &&
122 fix_problem(ctx
, PR_0_INVALID_QUOTA_INO
, &pctx
)) {
123 *quota_sb_inump(sb
, qtype
) = 0;
124 ext2fs_mark_super_dirty(fs
);