aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/quota
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/quota')
-rw-r--r--fs/xfs/quota/xfs_qm.c41
-rw-r--r--fs/xfs/quota/xfs_qm.h6
-rw-r--r--fs/xfs/quota/xfs_qm_bhv.c239
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c7
4 files changed, 39 insertions, 254 deletions
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 9567d1846ee5..8f5a43669297 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -288,45 +288,6 @@ xfs_qm_rele_quotafs_ref(
288} 288}
289 289
290/* 290/*
291 * This is called at mount time from xfs_mountfs to initialize the quotainfo
292 * structure and start the global quota manager (xfs_Gqm) if it hasn't done
293 * so already. Note that the superblock has not been read in yet.
294 */
295void
296xfs_qm_mount_quotainit(
297 xfs_mount_t *mp,
298 uint flags)
299{
300 /*
301 * User, projects or group quotas has to be on.
302 */
303 ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA));
304
305 /*
306 * Initialize the flags in the mount structure. From this point
307 * onwards we look at m_qflags to figure out if quotas's ON/OFF, etc.
308 * Note that we enforce nothing if accounting is off.
309 * ie. XFSMNT_*QUOTA must be ON for XFSMNT_*QUOTAENF.
310 * It isn't necessary to take the quotaoff lock to do this; this is
311 * called from mount.
312 */
313 if (flags & XFSMNT_UQUOTA) {
314 mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
315 if (flags & XFSMNT_UQUOTAENF)
316 mp->m_qflags |= XFS_UQUOTA_ENFD;
317 }
318 if (flags & XFSMNT_GQUOTA) {
319 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
320 if (flags & XFSMNT_GQUOTAENF)
321 mp->m_qflags |= XFS_OQUOTA_ENFD;
322 } else if (flags & XFSMNT_PQUOTA) {
323 mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
324 if (flags & XFSMNT_PQUOTAENF)
325 mp->m_qflags |= XFS_OQUOTA_ENFD;
326 }
327}
328
329/*
330 * Just destroy the quotainfo structure. 291 * Just destroy the quotainfo structure.
331 */ 292 */
332void 293void
@@ -1039,7 +1000,7 @@ xfs_qm_dqdetach(
1039int 1000int
1040xfs_qm_sync( 1001xfs_qm_sync(
1041 xfs_mount_t *mp, 1002 xfs_mount_t *mp,
1042 short flags) 1003 int flags)
1043{ 1004{
1044 int recl, restarts; 1005 int recl, restarts;
1045 xfs_dquot_t *dqp; 1006 xfs_dquot_t *dqp;
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h
index 689407de0a20..23ccaa5fceaf 100644
--- a/fs/xfs/quota/xfs_qm.h
+++ b/fs/xfs/quota/xfs_qm.h
@@ -166,12 +166,11 @@ typedef struct xfs_dquot_acct {
166 166
167extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); 167extern void xfs_qm_destroy_quotainfo(xfs_mount_t *);
168extern int xfs_qm_mount_quotas(xfs_mount_t *, int); 168extern int xfs_qm_mount_quotas(xfs_mount_t *, int);
169extern void xfs_qm_mount_quotainit(xfs_mount_t *, uint);
170extern int xfs_qm_quotacheck(xfs_mount_t *); 169extern int xfs_qm_quotacheck(xfs_mount_t *);
171extern void xfs_qm_unmount_quotadestroy(xfs_mount_t *); 170extern void xfs_qm_unmount_quotadestroy(xfs_mount_t *);
172extern int xfs_qm_unmount_quotas(xfs_mount_t *); 171extern int xfs_qm_unmount_quotas(xfs_mount_t *);
173extern int xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t); 172extern int xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t);
174extern int xfs_qm_sync(xfs_mount_t *, short); 173extern int xfs_qm_sync(xfs_mount_t *, int);
175 174
176/* dquot stuff */ 175/* dquot stuff */
177extern boolean_t xfs_qm_dqalloc_incore(xfs_dquot_t **); 176extern boolean_t xfs_qm_dqalloc_incore(xfs_dquot_t **);
@@ -199,7 +198,8 @@ extern void xfs_qm_freelist_unlink(xfs_dquot_t *);
199extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *); 198extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *);
200 199
201/* system call interface */ 200/* system call interface */
202extern int xfs_qm_quotactl(bhv_desc_t *, int, int, xfs_caddr_t); 201extern int xfs_qm_quotactl(struct xfs_mount *, int, int,
202 xfs_caddr_t);
203 203
204#ifdef DEBUG 204#ifdef DEBUG
205extern int xfs_qm_internalqcheck(xfs_mount_t *); 205extern int xfs_qm_internalqcheck(xfs_mount_t *);
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c
index ca25ee31a02f..97bb32937585 100644
--- a/fs/xfs/quota/xfs_qm_bhv.c
+++ b/fs/xfs/quota/xfs_qm_bhv.c
@@ -48,172 +48,13 @@
48#include "xfs_buf_item.h" 48#include "xfs_buf_item.h"
49#include "xfs_qm.h" 49#include "xfs_qm.h"
50 50
51#define MNTOPT_QUOTA "quota" /* disk quotas (user) */
52#define MNTOPT_NOQUOTA "noquota" /* no quotas */
53#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */
54#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */
55#define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */
56#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */
57#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */
58#define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */
59#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
60#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
61#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
62#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
63 51
64STATIC int 52STATIC void
65xfs_qm_parseargs( 53xfs_fill_statvfs_from_dquot(
66 struct bhv_desc *bhv,
67 char *options,
68 struct xfs_mount_args *args,
69 int update)
70{
71 size_t length;
72 char *local_options = options;
73 char *this_char;
74 int error;
75 int referenced = update;
76
77 while ((this_char = strsep(&local_options, ",")) != NULL) {
78 length = strlen(this_char);
79 if (local_options)
80 length++;
81
82 if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
83 args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA);
84 args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA);
85 referenced = update;
86 } else if (!strcmp(this_char, MNTOPT_QUOTA) ||
87 !strcmp(this_char, MNTOPT_UQUOTA) ||
88 !strcmp(this_char, MNTOPT_USRQUOTA)) {
89 args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF;
90 referenced = 1;
91 } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||
92 !strcmp(this_char, MNTOPT_UQUOTANOENF)) {
93 args->flags |= XFSMNT_UQUOTA;
94 args->flags &= ~XFSMNT_UQUOTAENF;
95 referenced = 1;
96 } else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
97 !strcmp(this_char, MNTOPT_PRJQUOTA)) {
98 args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF;
99 referenced = 1;
100 } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
101 args->flags |= XFSMNT_PQUOTA;
102 args->flags &= ~XFSMNT_PQUOTAENF;
103 referenced = 1;
104 } else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
105 !strcmp(this_char, MNTOPT_GRPQUOTA)) {
106 args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
107 referenced = 1;
108 } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
109 args->flags |= XFSMNT_GQUOTA;
110 args->flags &= ~XFSMNT_GQUOTAENF;
111 referenced = 1;
112 } else {
113 if (local_options)
114 *(local_options-1) = ',';
115 continue;
116 }
117
118 while (length--)
119 *this_char++ = ',';
120 }
121
122 if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) {
123 cmn_err(CE_WARN,
124 "XFS: cannot mount with both project and group quota");
125 return XFS_ERROR(EINVAL);
126 }
127
128 error = bhv_next_vfs_parseargs(BHV_NEXT(bhv), options, args, update);
129 if (!error && !referenced)
130 bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM);
131 return error;
132}
133
134STATIC int
135xfs_qm_showargs(
136 struct bhv_desc *bhv,
137 struct seq_file *m)
138{
139 struct bhv_vfs *vfsp = bhvtovfs(bhv);
140 struct xfs_mount *mp = XFS_VFSTOM(vfsp);
141
142 if (mp->m_qflags & XFS_UQUOTA_ACCT) {
143 (mp->m_qflags & XFS_UQUOTA_ENFD) ?
144 seq_puts(m, "," MNTOPT_USRQUOTA) :
145 seq_puts(m, "," MNTOPT_UQUOTANOENF);
146 }
147
148 if (mp->m_qflags & XFS_PQUOTA_ACCT) {
149 (mp->m_qflags & XFS_OQUOTA_ENFD) ?
150 seq_puts(m, "," MNTOPT_PRJQUOTA) :
151 seq_puts(m, "," MNTOPT_PQUOTANOENF);
152 }
153
154 if (mp->m_qflags & XFS_GQUOTA_ACCT) {
155 (mp->m_qflags & XFS_OQUOTA_ENFD) ?
156 seq_puts(m, "," MNTOPT_GRPQUOTA) :
157 seq_puts(m, "," MNTOPT_GQUOTANOENF);
158 }
159
160 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
161 seq_puts(m, "," MNTOPT_NOQUOTA);
162
163 return bhv_next_vfs_showargs(BHV_NEXT(bhv), m);
164}
165
166STATIC int
167xfs_qm_mount(
168 struct bhv_desc *bhv,
169 struct xfs_mount_args *args,
170 struct cred *cr)
171{
172 struct bhv_vfs *vfsp = bhvtovfs(bhv);
173 struct xfs_mount *mp = XFS_VFSTOM(vfsp);
174
175 if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA))
176 xfs_qm_mount_quotainit(mp, args->flags);
177 return bhv_next_vfs_mount(BHV_NEXT(bhv), args, cr);
178}
179
180/*
181 * Directory tree accounting is implemented using project quotas, where
182 * the project identifier is inherited from parent directories.
183 * A statvfs (df, etc.) of a directory that is using project quota should
184 * return a statvfs of the project, not the entire filesystem.
185 * This makes such trees appear as if they are filesystems in themselves.
186 */
187STATIC int
188xfs_qm_statvfs(
189 struct bhv_desc *bhv,
190 bhv_statvfs_t *statp, 54 bhv_statvfs_t *statp,
191 bhv_vnode_t *vnode) 55 xfs_disk_dquot_t *dp)
192{ 56{
193 xfs_mount_t *mp;
194 xfs_inode_t *ip;
195 xfs_dquot_t *dqp;
196 xfs_disk_dquot_t *dp;
197 __uint64_t limit; 57 __uint64_t limit;
198 int error;
199
200 error = bhv_next_vfs_statvfs(BHV_NEXT(bhv), statp, vnode);
201 if (error || !vnode)
202 return error;
203
204 mp = xfs_vfstom(bhvtovfs(bhv));
205 ip = xfs_vtoi(vnode);
206
207 if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT))
208 return 0;
209 if (!(mp->m_qflags & XFS_PQUOTA_ACCT))
210 return 0;
211 if (!(mp->m_qflags & XFS_OQUOTA_ENFD))
212 return 0;
213
214 if (xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp))
215 return 0;
216 dp = &dqp->q_core;
217 58
218 limit = dp->d_blk_softlimit ? 59 limit = dp->d_blk_softlimit ?
219 be64_to_cpu(dp->d_blk_softlimit) : 60 be64_to_cpu(dp->d_blk_softlimit) :
@@ -234,37 +75,35 @@ xfs_qm_statvfs(
234 (statp->f_files > be64_to_cpu(dp->d_icount)) ? 75 (statp->f_files > be64_to_cpu(dp->d_icount)) ?
235 (statp->f_ffree - be64_to_cpu(dp->d_icount)) : 0; 76 (statp->f_ffree - be64_to_cpu(dp->d_icount)) : 0;
236 } 77 }
237
238 xfs_qm_dqput(dqp);
239 return 0;
240} 78}
241 79
242STATIC int 80
243xfs_qm_syncall( 81/*
244 struct bhv_desc *bhv, 82 * Directory tree accounting is implemented using project quotas, where
245 int flags, 83 * the project identifier is inherited from parent directories.
246 cred_t *credp) 84 * A statvfs (df, etc.) of a directory that is using project quota should
85 * return a statvfs of the project, not the entire filesystem.
86 * This makes such trees appear as if they are filesystems in themselves.
87 */
88STATIC void
89xfs_qm_statvfs(
90 xfs_inode_t *ip,
91 bhv_statvfs_t *statp)
247{ 92{
248 struct bhv_vfs *vfsp = bhvtovfs(bhv); 93 xfs_mount_t *mp = ip->i_mount;
249 struct xfs_mount *mp = XFS_VFSTOM(vfsp); 94 xfs_dquot_t *dqp;
250 int error;
251 95
252 /* 96 if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) ||
253 * Get the Quota Manager to flush the dquots. 97 !((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
254 */ 98 (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))
255 if (XFS_IS_QUOTA_ON(mp)) { 99 return;
256 if ((error = xfs_qm_sync(mp, flags))) { 100
257 /* 101 if (!xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp)) {
258 * If we got an IO error, we will be shutting down. 102 xfs_disk_dquot_t *dp = &dqp->q_core;
259 * So, there's nothing more for us to do here. 103
260 */ 104 xfs_fill_statvfs_from_dquot(statp, dp);
261 ASSERT(error != EIO || XFS_FORCED_SHUTDOWN(mp)); 105 xfs_qm_dqput(dqp);
262 if (XFS_FORCED_SHUTDOWN(mp)) {
263 return XFS_ERROR(error);
264 }
265 }
266 } 106 }
267 return bhv_next_vfs_sync(BHV_NEXT(bhv), flags, credp);
268} 107}
269 108
270STATIC int 109STATIC int
@@ -382,7 +221,7 @@ xfs_qm_dqrele_null(
382} 221}
383 222
384 223
385static struct xfs_qmops xfs_qmcore_xfs = { 224struct xfs_qmops xfs_qmcore_xfs = {
386 .xfs_qminit = xfs_qm_newmount, 225 .xfs_qminit = xfs_qm_newmount,
387 .xfs_qmdone = xfs_qm_unmount_quotadestroy, 226 .xfs_qmdone = xfs_qm_unmount_quotadestroy,
388 .xfs_qmmount = xfs_qm_endmount, 227 .xfs_qmmount = xfs_qm_endmount,
@@ -396,36 +235,24 @@ static struct xfs_qmops xfs_qmcore_xfs = {
396 .xfs_dqvoprename = xfs_qm_vop_rename_dqattach, 235 .xfs_dqvoprename = xfs_qm_vop_rename_dqattach,
397 .xfs_dqvopchown = xfs_qm_vop_chown, 236 .xfs_dqvopchown = xfs_qm_vop_chown,
398 .xfs_dqvopchownresv = xfs_qm_vop_chown_reserve, 237 .xfs_dqvopchownresv = xfs_qm_vop_chown_reserve,
238 .xfs_dqstatvfs = xfs_qm_statvfs,
239 .xfs_dqsync = xfs_qm_sync,
240 .xfs_quotactl = xfs_qm_quotactl,
399 .xfs_dqtrxops = &xfs_trans_dquot_ops, 241 .xfs_dqtrxops = &xfs_trans_dquot_ops,
400}; 242};
401 243EXPORT_SYMBOL(xfs_qmcore_xfs);
402struct bhv_module_vfsops xfs_qmops = { {
403 BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM),
404 .vfs_parseargs = xfs_qm_parseargs,
405 .vfs_showargs = xfs_qm_showargs,
406 .vfs_mount = xfs_qm_mount,
407 .vfs_statvfs = xfs_qm_statvfs,
408 .vfs_sync = xfs_qm_syncall,
409 .vfs_quotactl = xfs_qm_quotactl, },
410};
411
412 244
413void __init 245void __init
414xfs_qm_init(void) 246xfs_qm_init(void)
415{ 247{
416 static char message[] __initdata = 248 printk(KERN_INFO "SGI XFS Quota Management subsystem\n");
417 KERN_INFO "SGI XFS Quota Management subsystem\n";
418
419 printk(message);
420 mutex_init(&xfs_Gqm_lock); 249 mutex_init(&xfs_Gqm_lock);
421 vfs_bhv_set_custom(&xfs_qmops, &xfs_qmcore_xfs);
422 xfs_qm_init_procfs(); 250 xfs_qm_init_procfs();
423} 251}
424 252
425void __exit 253void __exit
426xfs_qm_exit(void) 254xfs_qm_exit(void)
427{ 255{
428 vfs_bhv_clr_custom(&xfs_qmops);
429 xfs_qm_cleanup_procfs(); 256 xfs_qm_cleanup_procfs();
430 if (qm_dqzone) 257 if (qm_dqzone)
431 kmem_zone_destroy(qm_dqzone); 258 kmem_zone_destroy(qm_dqzone);
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index 2df67fd913e5..e0d024e73453 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -81,17 +81,14 @@ STATIC void xfs_qm_export_dquot(xfs_mount_t *, xfs_disk_dquot_t *,
81 */ 81 */
82int 82int
83xfs_qm_quotactl( 83xfs_qm_quotactl(
84 struct bhv_desc *bdp, 84 xfs_mount_t *mp,
85 int cmd, 85 int cmd,
86 int id, 86 int id,
87 xfs_caddr_t addr) 87 xfs_caddr_t addr)
88{ 88{
89 xfs_mount_t *mp; 89 bhv_vfs_t *vfsp = XFS_MTOVFS(mp);
90 bhv_vfs_t *vfsp;
91 int error; 90 int error;
92 91
93 vfsp = bhvtovfs(bdp);
94 mp = XFS_VFSTOM(vfsp);
95 92
96 ASSERT(addr != NULL || cmd == Q_XQUOTASYNC); 93 ASSERT(addr != NULL || cmd == Q_XQUOTASYNC);
97 94