quota.c revision ec7686e3e723ac8644a48ade6b58a1ca8dab6599
175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen/*
275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen * quota.c --- code for handling ext4 quota inodes
375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen *
475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen */
575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen#include "config.h"
775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen#ifdef HAVE_SYS_MOUNT_H
875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen#include <sys/param.h>
975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen#include <sys/mount.h>
1075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen#define MNT_FL (MS_MGC_VAL | MS_RDONLY)
1175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen#endif
1275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen#ifdef HAVE_SYS_STAT_H
1375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen#include <sys/stat.h>
1475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen#endif
1575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
1675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen#include "e2fsck.h"
1775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen#include "problem.h"
1875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen#include "quota/mkquota.h"
1975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen#include "quota/quotaio.h"
2075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
2175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenstatic void move_quota_inode(ext2_filsys fs, ext2_ino_t from_ino,
2275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen			     ext2_ino_t to_ino, int qtype)
2375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen{
2475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	struct ext2_inode	inode;
2575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	char			qf_name[QUOTA_NAME_LEN];
2675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
2775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	/* We need the inode bitmap to be loaded */
2875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	if (ext2fs_read_bitmaps(fs))
2975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen		return;
3075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
3175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	if (ext2fs_read_inode(fs, from_ino, &inode))
3275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen		return;
3375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
3475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	inode.i_links_count = 1;
3575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	inode.i_mode = LINUX_S_IFREG | 0600;
3675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	inode.i_flags = EXT2_IMMUTABLE_FL;
3775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	if (fs->super->s_feature_incompat &
3875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen			EXT3_FEATURE_INCOMPAT_EXTENTS)
3921416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata		inode.i_flags |= EXT4_EXTENTS_FL;
4075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
4175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	ext2fs_write_new_inode(fs, to_ino, &inode);
4275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	/* unlink the old inode */
4321416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata	quota_get_qf_name(qtype, QFMT_VFS_V1, qf_name);
4475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	ext2fs_unlink(fs, EXT2_ROOT_INO, qf_name, from_ino, 0);
4575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	ext2fs_inode_alloc_stats(fs, from_ino, -1);
4675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	/* Clear out the original inode in the inode-table block. */
4775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	memset(&inode, 0, sizeof(struct ext2_inode));
4875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	ext2fs_write_inode(fs, from_ino, &inode);
4975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen}
5021416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata
5121416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granatavoid e2fsck_hide_quota(e2fsck_t ctx)
5221416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata{
5321416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata	struct ext2_super_block *sb = ctx->fs->super;
5421416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata	struct problem_context	pctx;
5521416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata	ext2_filsys		fs = ctx->fs;
5675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
5775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	clear_problem_context(&pctx);
5875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
5975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	if ((ctx->options & E2F_OPT_READONLY) ||
6075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	    !(sb->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_QUOTA))
6175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen		return;
6275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
6375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	pctx.ino = sb->s_usr_quota_inum;
6475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	if (sb->s_usr_quota_inum &&
6575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	    (sb->s_usr_quota_inum != EXT4_USR_QUOTA_INO) &&
6675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	    fix_problem(ctx, PR_0_HIDE_QUOTA, &pctx)) {
6775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen		move_quota_inode(fs, sb->s_usr_quota_inum, EXT4_USR_QUOTA_INO,
6875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen				 USRQUOTA);
6975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen		sb->s_usr_quota_inum = EXT4_USR_QUOTA_INO;
7075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	}
7175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
7275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	pctx.ino = sb->s_grp_quota_inum;
7375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	if (sb->s_grp_quota_inum &&
7475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	    (sb->s_grp_quota_inum != EXT4_GRP_QUOTA_INO) &&
7575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	    fix_problem(ctx, PR_0_HIDE_QUOTA, &pctx)) {
7675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen		move_quota_inode(fs, sb->s_grp_quota_inum, EXT4_GRP_QUOTA_INO,
7775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen				 GRPQUOTA);
7875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen		sb->s_grp_quota_inum = EXT4_GRP_QUOTA_INO;
7975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	}
8075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
8175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen	return;
8275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen}
8375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen