1 /* 2 * quota.c --- code for handling ext4 quota inodes 3 * 4 */ 5 6 #ifdef HAVE_SYS_MOUNT_H 7 #include <sys/param.h> 8 #include <sys/mount.h> 9 #define MNT_FL (MS_MGC_VAL | MS_RDONLY) 10 #endif 11 #ifdef HAVE_SYS_STAT_H 12 #include <sys/stat.h> 13 #endif 14 15 #include "e2fsck.h" 16 #include "problem.h" 17 #include "quota/mkquota.h" 18 #include "quota/quotaio.h" 19 20 static void move_quota_inode(ext2_filsys fs, ext2_ino_t from_ino, 21 ext2_ino_t to_ino, int qtype) 22 { 23 struct ext2_inode inode; 24 char qf_name[QUOTA_NAME_LEN]; 25 26 /* We need the inode bitmap to be loaded */ 27 if (ext2fs_read_bitmaps(fs)) 28 return; 29 30 if (ext2fs_read_inode(fs, from_ino, &inode)) 31 return; 32 33 inode.i_links_count = 1; 34 inode.i_mode = LINUX_S_IFREG | 0600; 35 inode.i_flags = EXT2_IMMUTABLE_FL; 36 if (fs->super->s_feature_incompat & 37 EXT3_FEATURE_INCOMPAT_EXTENTS) 38 inode.i_flags |= EXT4_EXTENTS_FL; 39 40 ext2fs_write_new_inode(fs, to_ino, &inode); 41 /* unlink the old inode */ 42 quota_get_qf_name(qtype, QFMT_VFS_V1, qf_name); 43 ext2fs_unlink(fs, EXT2_ROOT_INO, qf_name, from_ino, 0); 44 ext2fs_inode_alloc_stats(fs, from_ino, -1); 45 /* Clear out the original inode in the inode-table block. */ 46 memset(&inode, 0, sizeof(struct ext2_inode)); 47 ext2fs_write_inode(fs, from_ino, &inode); 48 } 49 50 void e2fsck_hide_quota(e2fsck_t ctx) 51 { 52 struct ext2_super_block *sb = ctx->fs->super; 53 struct problem_context pctx; 54 ext2_filsys fs = ctx->fs; 55 56 clear_problem_context(&pctx); 57 58 if ((ctx->options & E2F_OPT_READONLY) || 59 !(sb->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_QUOTA)) 60 return; 61 62 pctx.ino = sb->s_usr_quota_inum; 63 if (sb->s_usr_quota_inum && 64 (sb->s_usr_quota_inum != EXT4_USR_QUOTA_INO) && 65 fix_problem(ctx, PR_0_HIDE_QUOTA, &pctx)) { 66 move_quota_inode(fs, sb->s_usr_quota_inum, EXT4_USR_QUOTA_INO, 67 USRQUOTA); 68 sb->s_usr_quota_inum = EXT4_USR_QUOTA_INO; 69 } 70 71 pctx.ino = sb->s_grp_quota_inum; 72 if (sb->s_grp_quota_inum && 73 (sb->s_grp_quota_inum != EXT4_GRP_QUOTA_INO) && 74 fix_problem(ctx, PR_0_HIDE_QUOTA, &pctx)) { 75 move_quota_inode(fs, sb->s_grp_quota_inum, EXT4_GRP_QUOTA_INO, 76 GRPQUOTA); 77 sb->s_grp_quota_inum = EXT4_GRP_QUOTA_INO; 78 } 79 80 return; 81 } 82