aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c10
-rw-r--r--fs/xfs/linux-2.6/xfs_super.h3
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.c15
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.h5
-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
-rw-r--r--fs/xfs/xfs_mount.h43
-rw-r--r--fs/xfs/xfs_qmops.c38
-rw-r--r--fs/xfs/xfs_quota.h10
-rw-r--r--fs/xfs/xfs_vfsops.c110
12 files changed, 224 insertions, 303 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 24073f8a292b..103add6eccb6 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -729,7 +729,7 @@ xfs_fs_quotasync(
729 struct super_block *sb, 729 struct super_block *sb,
730 int type) 730 int type)
731{ 731{
732 return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XQUOTASYNC, 0, NULL); 732 return -XFS_QM_QUOTACTL(XFS_M(sb), Q_XQUOTASYNC, 0, NULL);
733} 733}
734 734
735STATIC int 735STATIC int
@@ -737,7 +737,7 @@ xfs_fs_getxstate(
737 struct super_block *sb, 737 struct super_block *sb,
738 struct fs_quota_stat *fqs) 738 struct fs_quota_stat *fqs)
739{ 739{
740 return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XGETQSTAT, 0, (caddr_t)fqs); 740 return -XFS_QM_QUOTACTL(XFS_M(sb), Q_XGETQSTAT, 0, (caddr_t)fqs);
741} 741}
742 742
743STATIC int 743STATIC int
@@ -746,7 +746,7 @@ xfs_fs_setxstate(
746 unsigned int flags, 746 unsigned int flags,
747 int op) 747 int op)
748{ 748{
749 return -bhv_vfs_quotactl(vfs_from_sb(sb), op, 0, (caddr_t)&flags); 749 return -XFS_QM_QUOTACTL(XFS_M(sb), op, 0, (caddr_t)&flags);
750} 750}
751 751
752STATIC int 752STATIC int
@@ -756,7 +756,7 @@ xfs_fs_getxquota(
756 qid_t id, 756 qid_t id,
757 struct fs_disk_quota *fdq) 757 struct fs_disk_quota *fdq)
758{ 758{
759 return -bhv_vfs_quotactl(vfs_from_sb(sb), 759 return -XFS_QM_QUOTACTL(XFS_M(sb),
760 (type == USRQUOTA) ? Q_XGETQUOTA : 760 (type == USRQUOTA) ? Q_XGETQUOTA :
761 ((type == GRPQUOTA) ? Q_XGETGQUOTA : 761 ((type == GRPQUOTA) ? Q_XGETGQUOTA :
762 Q_XGETPQUOTA), id, (caddr_t)fdq); 762 Q_XGETPQUOTA), id, (caddr_t)fdq);
@@ -769,7 +769,7 @@ xfs_fs_setxquota(
769 qid_t id, 769 qid_t id,
770 struct fs_disk_quota *fdq) 770 struct fs_disk_quota *fdq)
771{ 771{
772 return -bhv_vfs_quotactl(vfs_from_sb(sb), 772 return -XFS_QM_QUOTACTL(XFS_M(sb),
773 (type == USRQUOTA) ? Q_XSETQLIM : 773 (type == USRQUOTA) ? Q_XSETQLIM :
774 ((type == GRPQUOTA) ? Q_XSETGQLIM : 774 ((type == GRPQUOTA) ? Q_XSETGQLIM :
775 Q_XSETPQLIM), id, (caddr_t)fdq); 775 Q_XSETPQLIM), id, (caddr_t)fdq);
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h
index ea2ee5a92637..4bbf985a7de7 100644
--- a/fs/xfs/linux-2.6/xfs_super.h
+++ b/fs/xfs/linux-2.6/xfs_super.h
@@ -119,4 +119,7 @@ extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
119 119
120extern struct export_operations xfs_export_operations; 120extern struct export_operations xfs_export_operations;
121 121
122#define XFS_M(sb) \
123 XFS_VFSTOM(vfs_from_sb(sb))
124
122#endif /* __XFS_SUPER_H__ */ 125#endif /* __XFS_SUPER_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_vfs.c b/fs/xfs/linux-2.6/xfs_vfs.c
index 1ce15706458a..5f616ccaea8d 100644
--- a/fs/xfs/linux-2.6/xfs_vfs.c
+++ b/fs/xfs/linux-2.6/xfs_vfs.c
@@ -155,21 +155,6 @@ vfs_vget(
155 return ((*bhvtovfsops(next)->vfs_vget)(next, vpp, fidp)); 155 return ((*bhvtovfsops(next)->vfs_vget)(next, vpp, fidp));
156} 156}
157 157
158int
159vfs_quotactl(
160 struct bhv_desc *bdp,
161 int cmd,
162 int id,
163 caddr_t addr)
164{
165 struct bhv_desc *next = bdp;
166
167 ASSERT(next);
168 while (! (bhvtovfsops(next))->vfs_quotactl)
169 next = BHV_NEXT(next);
170 return ((*bhvtovfsops(next)->vfs_quotactl)(next, cmd, id, addr));
171}
172
173void 158void
174vfs_init_vnode( 159vfs_init_vnode(
175 struct bhv_desc *bdp, 160 struct bhv_desc *bdp,
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h
index e63dbdbfd8a0..e63b2d012f0c 100644
--- a/fs/xfs/linux-2.6/xfs_vfs.h
+++ b/fs/xfs/linux-2.6/xfs_vfs.h
@@ -127,7 +127,6 @@ typedef int (*vfs_statvfs_t)(bhv_desc_t *, bhv_statvfs_t *,
127 struct inode *); 127 struct inode *);
128typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *); 128typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *);
129typedef int (*vfs_vget_t)(bhv_desc_t *, struct inode **, struct fid *); 129typedef int (*vfs_vget_t)(bhv_desc_t *, struct inode **, struct fid *);
130typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t);
131typedef void (*vfs_init_vnode_t)(bhv_desc_t *, 130typedef void (*vfs_init_vnode_t)(bhv_desc_t *,
132 struct inode *, struct xfs_inode *, int); 131 struct inode *, struct xfs_inode *, int);
133typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int); 132typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int);
@@ -144,7 +143,6 @@ typedef struct bhv_vfsops {
144 vfs_statvfs_t vfs_statvfs; /* file system statistics */ 143 vfs_statvfs_t vfs_statvfs; /* file system statistics */
145 vfs_sync_t vfs_sync; /* flush files */ 144 vfs_sync_t vfs_sync; /* flush files */
146 vfs_vget_t vfs_vget; /* get vnode from fid */ 145 vfs_vget_t vfs_vget; /* get vnode from fid */
147 vfs_quotactl_t vfs_quotactl; /* disk quota */
148 vfs_init_vnode_t vfs_init_vnode; /* initialize a new vnode */ 146 vfs_init_vnode_t vfs_init_vnode; /* initialize a new vnode */
149 vfs_force_shutdown_t vfs_force_shutdown; /* crash and burn */ 147 vfs_force_shutdown_t vfs_force_shutdown; /* crash and burn */
150 vfs_freeze_t vfs_freeze; /* freeze fs for snapshot */ 148 vfs_freeze_t vfs_freeze; /* freeze fs for snapshot */
@@ -163,7 +161,6 @@ typedef struct bhv_vfsops {
163#define bhv_vfs_statvfs(v, sp,vp) vfs_statvfs(VFSHEAD(v), sp,vp) 161#define bhv_vfs_statvfs(v, sp,vp) vfs_statvfs(VFSHEAD(v), sp,vp)
164#define bhv_vfs_sync(v, flag,cr) vfs_sync(VFSHEAD(v), flag,cr) 162#define bhv_vfs_sync(v, flag,cr) vfs_sync(VFSHEAD(v), flag,cr)
165#define bhv_vfs_vget(v, vpp,fidp) vfs_vget(VFSHEAD(v), vpp,fidp) 163#define bhv_vfs_vget(v, vpp,fidp) vfs_vget(VFSHEAD(v), vpp,fidp)
166#define bhv_vfs_quotactl(v, c,id,p) vfs_quotactl(VFSHEAD(v), c,id,p)
167#define bhv_vfs_init_vnode(v, vp,b,ul) vfs_init_vnode(VFSHEAD(v), vp,b,ul) 164#define bhv_vfs_init_vnode(v, vp,b,ul) vfs_init_vnode(VFSHEAD(v), vp,b,ul)
168#define bhv_vfs_force_shutdown(v,u,f,l) vfs_force_shutdown(VFSHEAD(v), u,f,l) 165#define bhv_vfs_force_shutdown(v,u,f,l) vfs_force_shutdown(VFSHEAD(v), u,f,l)
169#define bhv_vfs_freeze(v) vfs_freeze(VFSHEAD(v)) 166#define bhv_vfs_freeze(v) vfs_freeze(VFSHEAD(v))
@@ -180,7 +177,6 @@ typedef struct bhv_vfsops {
180#define bhv_next_vfs_statvfs(b, sp,vp) vfs_statvfs(b, sp,vp) 177#define bhv_next_vfs_statvfs(b, sp,vp) vfs_statvfs(b, sp,vp)
181#define bhv_next_vfs_sync(b, flag,cr) vfs_sync(b, flag,cr) 178#define bhv_next_vfs_sync(b, flag,cr) vfs_sync(b, flag,cr)
182#define bhv_next_vfs_vget(b, vpp,fidp) vfs_vget(b, vpp,fidp) 179#define bhv_next_vfs_vget(b, vpp,fidp) vfs_vget(b, vpp,fidp)
183#define bhv_next_vfs_quotactl(b, c,id,p) vfs_quotactl(b, c,id,p)
184#define bhv_next_vfs_init_vnode(b, vp,b2,ul) vfs_init_vnode(b, vp,b2,ul) 180#define bhv_next_vfs_init_vnode(b, vp,b2,ul) vfs_init_vnode(b, vp,b2,ul)
185#define bhv_next_force_shutdown(b, fl,f,l) vfs_force_shutdown(b, fl,f,l) 181#define bhv_next_force_shutdown(b, fl,f,l) vfs_force_shutdown(b, fl,f,l)
186#define bhv_next_vfs_freeze(b) vfs_freeze(b) 182#define bhv_next_vfs_freeze(b) vfs_freeze(b)
@@ -194,7 +190,6 @@ extern int vfs_root(bhv_desc_t *, struct inode **);
194extern int vfs_statvfs(bhv_desc_t *, bhv_statvfs_t *, struct inode *); 190extern int vfs_statvfs(bhv_desc_t *, bhv_statvfs_t *, struct inode *);
195extern int vfs_sync(bhv_desc_t *, int, struct cred *); 191extern int vfs_sync(bhv_desc_t *, int, struct cred *);
196extern int vfs_vget(bhv_desc_t *, struct inode **, struct fid *); 192extern int vfs_vget(bhv_desc_t *, struct inode **, struct fid *);
197extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t);
198extern void vfs_init_vnode(bhv_desc_t *, struct inode *, struct xfs_inode *, int); 193extern void vfs_init_vnode(bhv_desc_t *, struct inode *, struct xfs_inode *, int);
199extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int); 194extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int);
200extern void vfs_freeze(bhv_desc_t *); 195extern void vfs_freeze(bhv_desc_t *);
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
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index a7cd596ec6d2..594d7856c77e 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -142,6 +142,9 @@ typedef struct xfs_dquot * (*xfs_dqvopchown_t)(
142 struct xfs_dquot **, struct xfs_dquot *); 142 struct xfs_dquot **, struct xfs_dquot *);
143typedef int (*xfs_dqvopchownresv_t)(struct xfs_trans *, struct xfs_inode *, 143typedef int (*xfs_dqvopchownresv_t)(struct xfs_trans *, struct xfs_inode *,
144 struct xfs_dquot *, struct xfs_dquot *, uint); 144 struct xfs_dquot *, struct xfs_dquot *, uint);
145typedef void (*xfs_dqstatvfs_t)(struct xfs_inode *, bhv_statvfs_t *);
146typedef int (*xfs_dqsync_t)(struct xfs_mount *, int flags);
147typedef int (*xfs_quotactl_t)(struct xfs_mount *, int, int, xfs_caddr_t);
145 148
146typedef struct xfs_qmops { 149typedef struct xfs_qmops {
147 xfs_qminit_t xfs_qminit; 150 xfs_qminit_t xfs_qminit;
@@ -157,35 +160,44 @@ typedef struct xfs_qmops {
157 xfs_dqvoprename_t xfs_dqvoprename; 160 xfs_dqvoprename_t xfs_dqvoprename;
158 xfs_dqvopchown_t xfs_dqvopchown; 161 xfs_dqvopchown_t xfs_dqvopchown;
159 xfs_dqvopchownresv_t xfs_dqvopchownresv; 162 xfs_dqvopchownresv_t xfs_dqvopchownresv;
163 xfs_dqstatvfs_t xfs_dqstatvfs;
164 xfs_dqsync_t xfs_dqsync;
165 xfs_quotactl_t xfs_quotactl;
160 struct xfs_dqtrxops *xfs_dqtrxops; 166 struct xfs_dqtrxops *xfs_dqtrxops;
161} xfs_qmops_t; 167} xfs_qmops_t;
162 168
163#define XFS_QM_INIT(mp, mnt, fl) \ 169#define XFS_QM_INIT(mp, mnt, fl) \
164 (*(mp)->m_qm_ops.xfs_qminit)(mp, mnt, fl) 170 (*(mp)->m_qm_ops->xfs_qminit)(mp, mnt, fl)
165#define XFS_QM_MOUNT(mp, mnt, fl, mfsi_flags) \ 171#define XFS_QM_MOUNT(mp, mnt, fl, mfsi_flags) \
166 (*(mp)->m_qm_ops.xfs_qmmount)(mp, mnt, fl, mfsi_flags) 172 (*(mp)->m_qm_ops->xfs_qmmount)(mp, mnt, fl, mfsi_flags)
167#define XFS_QM_UNMOUNT(mp) \ 173#define XFS_QM_UNMOUNT(mp) \
168 (*(mp)->m_qm_ops.xfs_qmunmount)(mp) 174 (*(mp)->m_qm_ops->xfs_qmunmount)(mp)
169#define XFS_QM_DONE(mp) \ 175#define XFS_QM_DONE(mp) \
170 (*(mp)->m_qm_ops.xfs_qmdone)(mp) 176 (*(mp)->m_qm_ops->xfs_qmdone)(mp)
171#define XFS_QM_DQRELE(mp, dq) \ 177#define XFS_QM_DQRELE(mp, dq) \
172 (*(mp)->m_qm_ops.xfs_dqrele)(dq) 178 (*(mp)->m_qm_ops->xfs_dqrele)(dq)
173#define XFS_QM_DQATTACH(mp, ip, fl) \ 179#define XFS_QM_DQATTACH(mp, ip, fl) \
174 (*(mp)->m_qm_ops.xfs_dqattach)(ip, fl) 180 (*(mp)->m_qm_ops->xfs_dqattach)(ip, fl)
175#define XFS_QM_DQDETACH(mp, ip) \ 181#define XFS_QM_DQDETACH(mp, ip) \
176 (*(mp)->m_qm_ops.xfs_dqdetach)(ip) 182 (*(mp)->m_qm_ops->xfs_dqdetach)(ip)
177#define XFS_QM_DQPURGEALL(mp, fl) \ 183#define XFS_QM_DQPURGEALL(mp, fl) \
178 (*(mp)->m_qm_ops.xfs_dqpurgeall)(mp, fl) 184 (*(mp)->m_qm_ops->xfs_dqpurgeall)(mp, fl)
179#define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, prid, fl, dq1, dq2) \ 185#define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, prid, fl, dq1, dq2) \
180 (*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2) 186 (*(mp)->m_qm_ops->xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2)
181#define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \ 187#define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \
182 (*(mp)->m_qm_ops.xfs_dqvopcreate)(tp, ip, dq1, dq2) 188 (*(mp)->m_qm_ops->xfs_dqvopcreate)(tp, ip, dq1, dq2)
183#define XFS_QM_DQVOPRENAME(mp, ip) \ 189#define XFS_QM_DQVOPRENAME(mp, ip) \
184 (*(mp)->m_qm_ops.xfs_dqvoprename)(ip) 190 (*(mp)->m_qm_ops->xfs_dqvoprename)(ip)
185#define XFS_QM_DQVOPCHOWN(mp, tp, ip, dqp, dq) \ 191#define XFS_QM_DQVOPCHOWN(mp, tp, ip, dqp, dq) \
186 (*(mp)->m_qm_ops.xfs_dqvopchown)(tp, ip, dqp, dq) 192 (*(mp)->m_qm_ops->xfs_dqvopchown)(tp, ip, dqp, dq)
187#define XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, dq1, dq2, fl) \ 193#define XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, dq1, dq2, fl) \
188 (*(mp)->m_qm_ops.xfs_dqvopchownresv)(tp, ip, dq1, dq2, fl) 194 (*(mp)->m_qm_ops->xfs_dqvopchownresv)(tp, ip, dq1, dq2, fl)
195#define XFS_QM_DQSTATVFS(ip, statp) \
196 (*(ip)->i_mount->m_qm_ops->xfs_dqstatvfs)(ip, statp)
197#define XFS_QM_DQSYNC(mp, flags) \
198 (*(mp)->m_qm_ops->xfs_dqsync)(mp, flags)
199#define XFS_QM_QUOTACTL(mp, cmd, id, addr) \
200 (*(mp)->m_qm_ops->xfs_quotactl)(mp, cmd, id, addr)
189 201
190 202
191/* 203/*
@@ -413,7 +425,7 @@ typedef struct xfs_mount {
413 struct xfs_chash *m_chash; /* fs private inode per-cluster 425 struct xfs_chash *m_chash; /* fs private inode per-cluster
414 * hash table */ 426 * hash table */
415 struct xfs_dmops *m_dm_ops; /* vector of DMI ops */ 427 struct xfs_dmops *m_dm_ops; /* vector of DMI ops */
416 struct xfs_qmops m_qm_ops; /* vector of XQM ops */ 428 struct xfs_qmops *m_qm_ops; /* vector of XQM ops */
417 struct xfs_ioops m_io_ops; /* vector of I/O ops */ 429 struct xfs_ioops m_io_ops; /* vector of I/O ops */
418 atomic_t m_active_trans; /* number trans frozen */ 430 atomic_t m_active_trans; /* number trans frozen */
419#ifdef HAVE_PERCPU_SB 431#ifdef HAVE_PERCPU_SB
@@ -649,9 +661,10 @@ extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t);
649 661
650extern int xfs_dmops_get(struct xfs_mount *, struct xfs_mount_args *); 662extern int xfs_dmops_get(struct xfs_mount *, struct xfs_mount_args *);
651extern void xfs_dmops_put(struct xfs_mount *); 663extern void xfs_dmops_put(struct xfs_mount *);
664extern int xfs_qmops_get(struct xfs_mount *, struct xfs_mount_args *);
665extern void xfs_qmops_put(struct xfs_mount *);
652 666
653extern struct xfs_dmops xfs_dmcore_xfs; 667extern struct xfs_dmops xfs_dmcore_xfs;
654extern struct xfs_qmops xfs_qmcore_stub;
655extern struct xfs_ioops xfs_iocore_xfs; 668extern struct xfs_ioops xfs_iocore_xfs;
656 669
657extern int xfs_init(void); 670extern int xfs_init(void);
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c
index 0d594ed7efef..ea08bd8e8b80 100644
--- a/fs/xfs/xfs_qmops.c
+++ b/fs/xfs/xfs_qmops.c
@@ -28,6 +28,8 @@
28#include "xfs_mount.h" 28#include "xfs_mount.h"
29#include "xfs_quota.h" 29#include "xfs_quota.h"
30#include "xfs_error.h" 30#include "xfs_error.h"
31#include "xfs_clnt.h"
32
31 33
32STATIC struct xfs_dquot * 34STATIC struct xfs_dquot *
33xfs_dqvopchown_default( 35xfs_dqvopchown_default(
@@ -110,7 +112,7 @@ xfs_noquota_init(
110 return error; 112 return error;
111} 113}
112 114
113xfs_qmops_t xfs_qmcore_stub = { 115static struct xfs_qmops xfs_qmcore_stub = {
114 .xfs_qminit = (xfs_qminit_t) xfs_noquota_init, 116 .xfs_qminit = (xfs_qminit_t) xfs_noquota_init,
115 .xfs_qmdone = (xfs_qmdone_t) fs_noerr, 117 .xfs_qmdone = (xfs_qmdone_t) fs_noerr,
116 .xfs_qmmount = (xfs_qmmount_t) fs_noerr, 118 .xfs_qmmount = (xfs_qmmount_t) fs_noerr,
@@ -124,4 +126,38 @@ xfs_qmops_t xfs_qmcore_stub = {
124 .xfs_dqvoprename = (xfs_dqvoprename_t) fs_noerr, 126 .xfs_dqvoprename = (xfs_dqvoprename_t) fs_noerr,
125 .xfs_dqvopchown = xfs_dqvopchown_default, 127 .xfs_dqvopchown = xfs_dqvopchown_default,
126 .xfs_dqvopchownresv = (xfs_dqvopchownresv_t) fs_noerr, 128 .xfs_dqvopchownresv = (xfs_dqvopchownresv_t) fs_noerr,
129 .xfs_dqstatvfs = (xfs_dqstatvfs_t) fs_noval,
130 .xfs_dqsync = (xfs_dqsync_t) fs_noerr,
131 .xfs_quotactl = (xfs_quotactl_t) fs_nosys,
127}; 132};
133
134int
135xfs_qmops_get(struct xfs_mount *mp, struct xfs_mount_args *args)
136{
137 if (args->flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA)) {
138 struct xfs_qmops *ops;
139
140 ops = symbol_get(xfs_qmcore_xfs);
141 if (!ops) {
142 request_module("xfs_quota");
143 ops = symbol_get(xfs_qmcore_xfs);
144 }
145
146 if (!ops) {
147 cmn_err(CE_WARN, "XFS: no quota support available.");
148 return EINVAL;
149 }
150 mp->m_qm_ops = ops;
151 } else {
152 mp->m_qm_ops = &xfs_qmcore_stub;
153 }
154
155 return 0;
156}
157
158void
159xfs_qmops_put(struct xfs_mount *mp)
160{
161 if (mp->m_qm_ops != &xfs_qmcore_stub)
162 symbol_put(xfs_qmcore_xfs);
163}
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 6f14df976f73..12c4ec775af8 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -330,12 +330,12 @@ typedef struct xfs_dqtrxops {
330} xfs_dqtrxops_t; 330} xfs_dqtrxops_t;
331 331
332#define XFS_DQTRXOP(mp, tp, op, args...) \ 332#define XFS_DQTRXOP(mp, tp, op, args...) \
333 ((mp)->m_qm_ops.xfs_dqtrxops ? \ 333 ((mp)->m_qm_ops->xfs_dqtrxops ? \
334 ((mp)->m_qm_ops.xfs_dqtrxops->op)(tp, ## args) : 0) 334 ((mp)->m_qm_ops->xfs_dqtrxops->op)(tp, ## args) : 0)
335 335
336#define XFS_DQTRXOP_VOID(mp, tp, op, args...) \ 336#define XFS_DQTRXOP_VOID(mp, tp, op, args...) \
337 ((mp)->m_qm_ops.xfs_dqtrxops ? \ 337 ((mp)->m_qm_ops->xfs_dqtrxops ? \
338 ((mp)->m_qm_ops.xfs_dqtrxops->op)(tp, ## args) : (void)0) 338 ((mp)->m_qm_ops->xfs_dqtrxops->op)(tp, ## args) : (void)0)
339 339
340#define XFS_TRANS_DUP_DQINFO(mp, otp, ntp) \ 340#define XFS_TRANS_DUP_DQINFO(mp, otp, ntp) \
341 XFS_DQTRXOP_VOID(mp, otp, qo_dup_dqinfo, ntp) 341 XFS_DQTRXOP_VOID(mp, otp, qo_dup_dqinfo, ntp)
@@ -364,7 +364,7 @@ typedef struct xfs_dqtrxops {
364extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *); 364extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *);
365extern int xfs_mount_reset_sbqflags(struct xfs_mount *); 365extern int xfs_mount_reset_sbqflags(struct xfs_mount *);
366 366
367extern struct bhv_module_vfsops xfs_qmops; 367extern struct xfs_qmops xfs_qmcore_xfs;
368 368
369#endif /* __KERNEL__ */ 369#endif /* __KERNEL__ */
370 370
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 1cf8f54d8aa9..f62f6e486f23 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -402,6 +402,22 @@ xfs_finish_flags(
402 return XFS_ERROR(EINVAL); 402 return XFS_ERROR(EINVAL);
403 } 403 }
404 404
405 if (ap->flags & XFSMNT_UQUOTA) {
406 mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
407 if (ap->flags & XFSMNT_UQUOTAENF)
408 mp->m_qflags |= XFS_UQUOTA_ENFD;
409 }
410
411 if (ap->flags & XFSMNT_GQUOTA) {
412 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
413 if (ap->flags & XFSMNT_GQUOTAENF)
414 mp->m_qflags |= XFS_OQUOTA_ENFD;
415 } else if (ap->flags & XFSMNT_PQUOTA) {
416 mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
417 if (ap->flags & XFSMNT_PQUOTAENF)
418 mp->m_qflags |= XFS_OQUOTA_ENFD;
419 }
420
405 return 0; 421 return 0;
406} 422}
407 423
@@ -435,12 +451,13 @@ xfs_mount(
435 error = xfs_dmops_get(mp, args); 451 error = xfs_dmops_get(mp, args);
436 if (error) 452 if (error)
437 return error; 453 return error;
454 error = xfs_qmops_get(mp, args);
455 if (error)
456 return error;
438 457
439 /* 458 /*
440 * Setup xfs_mount function vectors from available behaviors 459 * Setup xfs_mount function vectors from available behaviors
441 */ 460 */
442 p = vfs_bhv_lookup(vfsp, VFS_POSITION_QM);
443 mp->m_qm_ops = p ? *(xfs_qmops_t *) vfs_bhv_custom(p) : xfs_qmcore_stub;
444 p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO); 461 p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO);
445 mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs; 462 mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs;
446 463
@@ -556,6 +573,7 @@ error1:
556 xfs_binval(mp->m_rtdev_targp); 573 xfs_binval(mp->m_rtdev_targp);
557error0: 574error0:
558 xfs_unmountfs_close(mp, credp); 575 xfs_unmountfs_close(mp, credp);
576 xfs_qmops_put(mp);
559 xfs_dmops_put(mp); 577 xfs_dmops_put(mp);
560 return error; 578 return error;
561} 579}
@@ -647,6 +665,7 @@ out:
647 * and free the super block buffer & mount structures. 665 * and free the super block buffer & mount structures.
648 */ 666 */
649 xfs_unmountfs(mp, credp); 667 xfs_unmountfs(mp, credp);
668 xfs_qmops_put(mp);
650 xfs_dmops_put(mp); 669 xfs_dmops_put(mp);
651 kmem_free(mp, sizeof(xfs_mount_t)); 670 kmem_free(mp, sizeof(xfs_mount_t));
652 } 671 }
@@ -887,6 +906,8 @@ xfs_statvfs(
887 xfs_statvfs_fsid(statp, mp); 906 xfs_statvfs_fsid(statp, mp);
888 statp->f_namelen = MAXNAMELEN - 1; 907 statp->f_namelen = MAXNAMELEN - 1;
889 908
909 if (vp)
910 XFS_QM_DQSTATVFS(xfs_vtoi(vp), statp);
890 return 0; 911 return 0;
891} 912}
892 913
@@ -941,6 +962,25 @@ xfs_sync(
941 cred_t *credp) 962 cred_t *credp)
942{ 963{
943 xfs_mount_t *mp = XFS_BHVTOM(bdp); 964 xfs_mount_t *mp = XFS_BHVTOM(bdp);
965 int error;
966
967 /*
968 * Get the Quota Manager to flush the dquots.
969 *
970 * If XFS quota support is not enabled or this filesystem
971 * instance does not use quotas XFS_QM_DQSYNC will always
972 * return zero.
973 */
974 error = XFS_QM_DQSYNC(mp, flags);
975 if (error) {
976 /*
977 * If we got an IO error, we will be shutting down.
978 * So, there's nothing more for us to do here.
979 */
980 ASSERT(error != EIO || XFS_FORCED_SHUTDOWN(mp));
981 if (XFS_FORCED_SHUTDOWN(mp))
982 return XFS_ERROR(error);
983 }
944 984
945 if (flags & SYNC_IOWAIT) 985 if (flags & SYNC_IOWAIT)
946 xfs_filestream_flush(mp); 986 xfs_filestream_flush(mp);
@@ -1696,6 +1736,18 @@ xfs_vget(
1696#define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */ 1736#define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */
1697#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ 1737#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */
1698#define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */ 1738#define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */
1739#define MNTOPT_QUOTA "quota" /* disk quotas (user) */
1740#define MNTOPT_NOQUOTA "noquota" /* no quotas */
1741#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */
1742#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */
1743#define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */
1744#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */
1745#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */
1746#define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */
1747#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
1748#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
1749#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
1750#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
1699#define MNTOPT_DMAPI "dmapi" /* DMI enabled (DMAPI / XDSM) */ 1751#define MNTOPT_DMAPI "dmapi" /* DMI enabled (DMAPI / XDSM) */
1700#define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */ 1752#define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */
1701#define MNTOPT_DMI "dmi" /* DMI enabled (DMAPI / XDSM) */ 1753#define MNTOPT_DMI "dmi" /* DMI enabled (DMAPI / XDSM) */
@@ -1889,6 +1941,29 @@ xfs_parseargs(
1889 args->flags &= ~XFSMNT_ATTR2; 1941 args->flags &= ~XFSMNT_ATTR2;
1890 } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { 1942 } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) {
1891 args->flags2 |= XFSMNT2_FILESTREAMS; 1943 args->flags2 |= XFSMNT2_FILESTREAMS;
1944 } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
1945 args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA);
1946 args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA);
1947 } else if (!strcmp(this_char, MNTOPT_QUOTA) ||
1948 !strcmp(this_char, MNTOPT_UQUOTA) ||
1949 !strcmp(this_char, MNTOPT_USRQUOTA)) {
1950 args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF;
1951 } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||
1952 !strcmp(this_char, MNTOPT_UQUOTANOENF)) {
1953 args->flags |= XFSMNT_UQUOTA;
1954 args->flags &= ~XFSMNT_UQUOTAENF;
1955 } else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
1956 !strcmp(this_char, MNTOPT_PRJQUOTA)) {
1957 args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF;
1958 } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
1959 args->flags |= XFSMNT_PQUOTA;
1960 args->flags &= ~XFSMNT_PQUOTAENF;
1961 } else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
1962 !strcmp(this_char, MNTOPT_GRPQUOTA)) {
1963 args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
1964 } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
1965 args->flags |= XFSMNT_GQUOTA;
1966 args->flags &= ~XFSMNT_GQUOTAENF;
1892 } else if (!strcmp(this_char, MNTOPT_DMAPI)) { 1967 } else if (!strcmp(this_char, MNTOPT_DMAPI)) {
1893 args->flags |= XFSMNT_DMAPI; 1968 args->flags |= XFSMNT_DMAPI;
1894 } else if (!strcmp(this_char, MNTOPT_XDSM)) { 1969 } else if (!strcmp(this_char, MNTOPT_XDSM)) {
@@ -1926,6 +2001,12 @@ xfs_parseargs(
1926 return EINVAL; 2001 return EINVAL;
1927 } 2002 }
1928 2003
2004 if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) {
2005 cmn_err(CE_WARN,
2006 "XFS: cannot mount with both project and group quota");
2007 return EINVAL;
2008 }
2009
1929 if ((args->flags & XFSMNT_DMAPI) && *args->mtpt == '\0') { 2010 if ((args->flags & XFSMNT_DMAPI) && *args->mtpt == '\0') {
1930 printk("XFS: %s option needs the mount point option as well\n", 2011 printk("XFS: %s option needs the mount point option as well\n",
1931 MNTOPT_DMAPI); 2012 MNTOPT_DMAPI);
@@ -2025,9 +2106,32 @@ xfs_showargs(
2025 if (vfsp->vfs_flag & VFS_GRPID) 2106 if (vfsp->vfs_flag & VFS_GRPID)
2026 seq_printf(m, "," MNTOPT_GRPID); 2107 seq_printf(m, "," MNTOPT_GRPID);
2027 2108
2109 if (mp->m_qflags & XFS_UQUOTA_ACCT) {
2110 if (mp->m_qflags & XFS_UQUOTA_ENFD)
2111 seq_puts(m, "," MNTOPT_USRQUOTA);
2112 else
2113 seq_puts(m, "," MNTOPT_UQUOTANOENF);
2114 }
2115
2116 if (mp->m_qflags & XFS_PQUOTA_ACCT) {
2117 if (mp->m_qflags & XFS_OQUOTA_ENFD)
2118 seq_puts(m, "," MNTOPT_PRJQUOTA);
2119 else
2120 seq_puts(m, "," MNTOPT_PQUOTANOENF);
2121 }
2122
2123 if (mp->m_qflags & XFS_GQUOTA_ACCT) {
2124 if (mp->m_qflags & XFS_OQUOTA_ENFD)
2125 seq_puts(m, "," MNTOPT_GRPQUOTA);
2126 else
2127 seq_puts(m, "," MNTOPT_GQUOTANOENF);
2128 }
2129
2130 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
2131 seq_puts(m, "," MNTOPT_NOQUOTA);
2132
2028 if (vfsp->vfs_flag & VFS_DMI) 2133 if (vfsp->vfs_flag & VFS_DMI)
2029 seq_puts(m, "," MNTOPT_DMAPI); 2134 seq_puts(m, "," MNTOPT_DMAPI);
2030
2031 return 0; 2135 return 0;
2032} 2136}
2033 2137