1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include "xfs.h"
19#include "xfs_fs.h"
20#include "xfs_bit.h"
21#include "xfs_log.h"
22#include "xfs_inum.h"
23#include "xfs_trans.h"
24#include "xfs_sb.h"
25#include "xfs_ag.h"
26#include "xfs_alloc.h"
27#include "xfs_quota.h"
28#include "xfs_mount.h"
29#include "xfs_bmap_btree.h"
30#include "xfs_inode.h"
31#include "xfs_itable.h"
32#include "xfs_bmap.h"
33#include "xfs_rtalloc.h"
34#include "xfs_error.h"
35#include "xfs_attr.h"
36#include "xfs_buf_item.h"
37#include "xfs_qm.h"
38
39
40STATIC void
41xfs_fill_statvfs_from_dquot(
42 struct kstatfs *statp,
43 xfs_disk_dquot_t *dp)
44{
45 __uint64_t limit;
46
47 limit = dp->d_blk_softlimit ?
48 be64_to_cpu(dp->d_blk_softlimit) :
49 be64_to_cpu(dp->d_blk_hardlimit);
50 if (limit && statp->f_blocks > limit) {
51 statp->f_blocks = limit;
52 statp->f_bfree = statp->f_bavail =
53 (statp->f_blocks > be64_to_cpu(dp->d_bcount)) ?
54 (statp->f_blocks - be64_to_cpu(dp->d_bcount)) : 0;
55 }
56
57 limit = dp->d_ino_softlimit ?
58 be64_to_cpu(dp->d_ino_softlimit) :
59 be64_to_cpu(dp->d_ino_hardlimit);
60 if (limit && statp->f_files > limit) {
61 statp->f_files = limit;
62 statp->f_ffree =
63 (statp->f_files > be64_to_cpu(dp->d_icount)) ?
64 (statp->f_ffree - be64_to_cpu(dp->d_icount)) : 0;
65 }
66}
67
68
69
70
71
72
73
74
75
76void
77xfs_qm_statvfs(
78 xfs_inode_t *ip,
79 struct kstatfs *statp)
80{
81 xfs_mount_t *mp = ip->i_mount;
82 xfs_dquot_t *dqp;
83
84 if (!xfs_qm_dqget(mp, NULL, xfs_get_projid(ip), XFS_DQ_PROJ, 0, &dqp)) {
85 xfs_fill_statvfs_from_dquot(statp, &dqp->q_core);
86 xfs_qm_dqput(dqp);
87 }
88}
89
90int
91xfs_qm_newmount(
92 xfs_mount_t *mp,
93 uint *needquotamount,
94 uint *quotaflags)
95{
96 uint quotaondisk;
97 uint uquotaondisk = 0, gquotaondisk = 0, pquotaondisk = 0;
98
99 quotaondisk = xfs_sb_version_hasquota(&mp->m_sb) &&
100 (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT);
101
102 if (quotaondisk) {
103 uquotaondisk = mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT;
104 pquotaondisk = mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT;
105 gquotaondisk = mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT;
106 }
107
108
109
110
111
112
113
114
115 if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) ||
116 (!uquotaondisk && XFS_IS_UQUOTA_ON(mp)) ||
117 (pquotaondisk && !XFS_IS_PQUOTA_ON(mp)) ||
118 (!pquotaondisk && XFS_IS_PQUOTA_ON(mp)) ||
119 (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) ||
120 (!gquotaondisk && XFS_IS_OQUOTA_ON(mp))) &&
121 xfs_dev_is_read_only(mp, "changing quota state")) {
122 cmn_err(CE_WARN,
123 "XFS: please mount with%s%s%s%s.",
124 (!quotaondisk ? "out quota" : ""),
125 (uquotaondisk ? " usrquota" : ""),
126 (pquotaondisk ? " prjquota" : ""),
127 (gquotaondisk ? " grpquota" : ""));
128 return XFS_ERROR(EPERM);
129 }
130
131 if (XFS_IS_QUOTA_ON(mp) || quotaondisk) {
132
133
134
135
136 if (quotaondisk && !XFS_QM_NEED_QUOTACHECK(mp)) {
137
138
139
140
141
142
143 xfs_qm_mount_quotas(mp);
144 } else {
145
146
147
148
149
150
151
152 *needquotamount = B_TRUE;
153 *quotaflags = mp->m_qflags;
154 mp->m_qflags = 0;
155 }
156 }
157
158 return 0;
159}
160
161void __init
162xfs_qm_init(void)
163{
164 printk(KERN_INFO "SGI XFS Quota Management subsystem\n");
165 mutex_init(&xfs_Gqm_lock);
166 xfs_qm_init_procfs();
167}
168
169void __exit
170xfs_qm_exit(void)
171{
172 xfs_qm_cleanup_procfs();
173 if (qm_dqzone)
174 kmem_zone_destroy(qm_dqzone);
175 if (qm_dqtrxzone)
176 kmem_zone_destroy(qm_dqtrxzone);
177}
178