]>
Commit | Line | Data |
---|---|---|
624e4a64 AK |
1 | /* |
2 | * quota.c --- code for handling ext4 quota inodes | |
3 | * | |
4 | */ | |
5 | ||
d1154eb4 | 6 | #include "config.h" |
624e4a64 AK |
7 | #ifdef HAVE_SYS_MOUNT_H |
8 | #include <sys/param.h> | |
9 | #include <sys/mount.h> | |
10 | #define MNT_FL (MS_MGC_VAL | MS_RDONLY) | |
11 | #endif | |
12 | #ifdef HAVE_SYS_STAT_H | |
13 | #include <sys/stat.h> | |
14 | #endif | |
15 | ||
16 | #include "e2fsck.h" | |
17 | #include "problem.h" | |
624e4a64 AK |
18 | |
19 | static void move_quota_inode(ext2_filsys fs, ext2_ino_t from_ino, | |
2d2d799c | 20 | ext2_ino_t to_ino, enum quota_type qtype) |
624e4a64 | 21 | { |
624e4a64 | 22 | struct ext2_inode inode; |
340493b6 | 23 | errcode_t retval; |
2f7d855c | 24 | char qf_name[QUOTA_NAME_LEN]; |
624e4a64 | 25 | |
ec7686e3 AK |
26 | /* We need the inode bitmap to be loaded */ |
27 | if (ext2fs_read_bitmaps(fs)) | |
28 | return; | |
29 | ||
340493b6 TT |
30 | retval = ext2fs_read_inode(fs, from_ino, &inode); |
31 | if (retval) { | |
4d46e6c7 AD |
32 | com_err("ext2fs_read_inode", retval, "%s", |
33 | _("in move_quota_inode")); | |
624e4a64 | 34 | return; |
340493b6 | 35 | } |
624e4a64 AK |
36 | |
37 | inode.i_links_count = 1; | |
38 | inode.i_mode = LINUX_S_IFREG | 0600; | |
39 | inode.i_flags = EXT2_IMMUTABLE_FL; | |
86f3b6cf | 40 | if (ext2fs_has_feature_extents(fs->super)) |
624e4a64 AK |
41 | inode.i_flags |= EXT4_EXTENTS_FL; |
42 | ||
340493b6 TT |
43 | retval = ext2fs_write_new_inode(fs, to_ino, &inode); |
44 | if (retval) { | |
4d46e6c7 | 45 | com_err("ext2fs_write_new_inode", retval, "%s", |
340493b6 TT |
46 | _("in move_quota_inode")); |
47 | return; | |
48 | } | |
49 | ||
624e4a64 | 50 | /* unlink the old inode */ |
a86d55da | 51 | quota_get_qf_name(qtype, QFMT_VFS_V1, qf_name); |
624e4a64 AK |
52 | ext2fs_unlink(fs, EXT2_ROOT_INO, qf_name, from_ino, 0); |
53 | ext2fs_inode_alloc_stats(fs, from_ino, -1); | |
ec7686e3 AK |
54 | /* Clear out the original inode in the inode-table block. */ |
55 | memset(&inode, 0, sizeof(struct ext2_inode)); | |
56 | ext2fs_write_inode(fs, from_ino, &inode); | |
624e4a64 AK |
57 | } |
58 | ||
59 | void e2fsck_hide_quota(e2fsck_t ctx) | |
60 | { | |
61 | struct ext2_super_block *sb = ctx->fs->super; | |
62 | struct problem_context pctx; | |
63 | ext2_filsys fs = ctx->fs; | |
2d2d799c LX |
64 | enum quota_type qtype; |
65 | ext2_ino_t quota_ino; | |
624e4a64 AK |
66 | |
67 | clear_problem_context(&pctx); | |
68 | ||
69 | if ((ctx->options & E2F_OPT_READONLY) || | |
86f3b6cf | 70 | !ext2fs_has_feature_quota(sb)) |
624e4a64 AK |
71 | return; |
72 | ||
2d2d799c | 73 | for (qtype = 0; qtype < MAXQUOTAS; qtype++) { |
27755289 | 74 | pctx.dir = 2; /* This is a guess, but it's a good one */ |
2d2d799c | 75 | pctx.ino = *quota_sb_inump(sb, qtype); |
27755289 | 76 | pctx.num = qtype; |
2d2d799c LX |
77 | quota_ino = quota_type2inum(qtype, fs->super); |
78 | if (pctx.ino && (pctx.ino != quota_ino) && | |
79 | fix_problem(ctx, PR_0_HIDE_QUOTA, &pctx)) { | |
80 | move_quota_inode(fs, pctx.ino, quota_ino, qtype); | |
81 | *quota_sb_inump(sb, qtype) = quota_ino; | |
d202f46d | 82 | ext2fs_mark_super_dirty(fs); |
2d2d799c | 83 | } |
624e4a64 AK |
84 | } |
85 | ||
86 | return; | |
87 | } | |
d202f46d TT |
88 | |
89 | void e2fsck_validate_quota_inodes(e2fsck_t ctx) | |
90 | { | |
91 | struct ext2_super_block *sb = ctx->fs->super; | |
92 | struct problem_context pctx; | |
93 | ext2_filsys fs = ctx->fs; | |
94 | enum quota_type qtype; | |
95 | ext2_ino_t quota_ino; | |
96 | ||
97 | clear_problem_context(&pctx); | |
98 | ||
99 | for (qtype = 0; qtype < MAXQUOTAS; qtype++) { | |
100 | pctx.ino = *quota_sb_inump(sb, qtype); | |
101 | pctx.num = qtype; | |
102 | if (pctx.ino && | |
103 | ((pctx.ino == EXT2_BAD_INO) || | |
104 | (pctx.ino == EXT2_ROOT_INO) || | |
105 | (pctx.ino == EXT2_BOOT_LOADER_INO) || | |
106 | (pctx.ino == EXT2_UNDEL_DIR_INO) || | |
107 | (pctx.ino == EXT2_RESIZE_INO) || | |
108 | (pctx.ino == EXT2_JOURNAL_INO) || | |
109 | (pctx.ino == EXT2_EXCLUDE_INO) || | |
110 | (pctx.ino == EXT4_REPLICA_INO) || | |
111 | (pctx.ino > fs->super->s_inodes_count)) && | |
112 | fix_problem(ctx, PR_0_INVALID_QUOTA_INO, &pctx)) { | |
113 | *quota_sb_inump(sb, qtype) = 0; | |
114 | ext2fs_mark_super_dirty(fs); | |
115 | } | |
116 | } | |
117 | } |