diff options
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 10 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.h | 3 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_vfs.c | 15 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_vfs.h | 5 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm.c | 41 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm.h | 6 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm_bhv.c | 239 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm_syscalls.c | 7 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.h | 43 | ||||
-rw-r--r-- | fs/xfs/xfs_qmops.c | 38 | ||||
-rw-r--r-- | fs/xfs/xfs_quota.h | 10 | ||||
-rw-r--r-- | fs/xfs/xfs_vfsops.c | 110 |
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 | ||
735 | STATIC int | 735 | STATIC 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 | ||
743 | STATIC int | 743 | STATIC 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 | ||
752 | STATIC int | 752 | STATIC 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 | ||
120 | extern struct export_operations xfs_export_operations; | 120 | extern 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 | ||
158 | int | ||
159 | vfs_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 | |||
173 | void | 158 | void |
174 | vfs_init_vnode( | 159 | vfs_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 *); |
128 | typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *); | 128 | typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *); |
129 | typedef int (*vfs_vget_t)(bhv_desc_t *, struct inode **, struct fid *); | 129 | typedef int (*vfs_vget_t)(bhv_desc_t *, struct inode **, struct fid *); |
130 | typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t); | ||
131 | typedef void (*vfs_init_vnode_t)(bhv_desc_t *, | 130 | typedef void (*vfs_init_vnode_t)(bhv_desc_t *, |
132 | struct inode *, struct xfs_inode *, int); | 131 | struct inode *, struct xfs_inode *, int); |
133 | typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int); | 132 | typedef 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 **); | |||
194 | extern int vfs_statvfs(bhv_desc_t *, bhv_statvfs_t *, struct inode *); | 190 | extern int vfs_statvfs(bhv_desc_t *, bhv_statvfs_t *, struct inode *); |
195 | extern int vfs_sync(bhv_desc_t *, int, struct cred *); | 191 | extern int vfs_sync(bhv_desc_t *, int, struct cred *); |
196 | extern int vfs_vget(bhv_desc_t *, struct inode **, struct fid *); | 192 | extern int vfs_vget(bhv_desc_t *, struct inode **, struct fid *); |
197 | extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t); | ||
198 | extern void vfs_init_vnode(bhv_desc_t *, struct inode *, struct xfs_inode *, int); | 193 | extern void vfs_init_vnode(bhv_desc_t *, struct inode *, struct xfs_inode *, int); |
199 | extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int); | 194 | extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int); |
200 | extern void vfs_freeze(bhv_desc_t *); | 195 | extern 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 | */ | ||
295 | void | ||
296 | xfs_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 | */ |
332 | void | 293 | void |
@@ -1039,7 +1000,7 @@ xfs_qm_dqdetach( | |||
1039 | int | 1000 | int |
1040 | xfs_qm_sync( | 1001 | xfs_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 | ||
167 | extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); | 167 | extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); |
168 | extern int xfs_qm_mount_quotas(xfs_mount_t *, int); | 168 | extern int xfs_qm_mount_quotas(xfs_mount_t *, int); |
169 | extern void xfs_qm_mount_quotainit(xfs_mount_t *, uint); | ||
170 | extern int xfs_qm_quotacheck(xfs_mount_t *); | 169 | extern int xfs_qm_quotacheck(xfs_mount_t *); |
171 | extern void xfs_qm_unmount_quotadestroy(xfs_mount_t *); | 170 | extern void xfs_qm_unmount_quotadestroy(xfs_mount_t *); |
172 | extern int xfs_qm_unmount_quotas(xfs_mount_t *); | 171 | extern int xfs_qm_unmount_quotas(xfs_mount_t *); |
173 | extern int xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t); | 172 | extern int xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t); |
174 | extern int xfs_qm_sync(xfs_mount_t *, short); | 173 | extern int xfs_qm_sync(xfs_mount_t *, int); |
175 | 174 | ||
176 | /* dquot stuff */ | 175 | /* dquot stuff */ |
177 | extern boolean_t xfs_qm_dqalloc_incore(xfs_dquot_t **); | 176 | extern boolean_t xfs_qm_dqalloc_incore(xfs_dquot_t **); |
@@ -199,7 +198,8 @@ extern void xfs_qm_freelist_unlink(xfs_dquot_t *); | |||
199 | extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *); | 198 | extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *); |
200 | 199 | ||
201 | /* system call interface */ | 200 | /* system call interface */ |
202 | extern int xfs_qm_quotactl(bhv_desc_t *, int, int, xfs_caddr_t); | 201 | extern int xfs_qm_quotactl(struct xfs_mount *, int, int, |
202 | xfs_caddr_t); | ||
203 | 203 | ||
204 | #ifdef DEBUG | 204 | #ifdef DEBUG |
205 | extern int xfs_qm_internalqcheck(xfs_mount_t *); | 205 | extern 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 | ||
64 | STATIC int | 52 | STATIC void |
65 | xfs_qm_parseargs( | 53 | xfs_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 | |||
134 | STATIC int | ||
135 | xfs_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 | |||
166 | STATIC int | ||
167 | xfs_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 | */ | ||
187 | STATIC int | ||
188 | xfs_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 | ||
242 | STATIC int | 80 | |
243 | xfs_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 | */ | ||
88 | STATIC void | ||
89 | xfs_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 | ||
270 | STATIC int | 109 | STATIC int |
@@ -382,7 +221,7 @@ xfs_qm_dqrele_null( | |||
382 | } | 221 | } |
383 | 222 | ||
384 | 223 | ||
385 | static struct xfs_qmops xfs_qmcore_xfs = { | 224 | struct 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 | 243 | EXPORT_SYMBOL(xfs_qmcore_xfs); | |
402 | struct 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 | ||
413 | void __init | 245 | void __init |
414 | xfs_qm_init(void) | 246 | xfs_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 | ||
425 | void __exit | 253 | void __exit |
426 | xfs_qm_exit(void) | 254 | xfs_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 | */ |
82 | int | 82 | int |
83 | xfs_qm_quotactl( | 83 | xfs_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 *); |
143 | typedef int (*xfs_dqvopchownresv_t)(struct xfs_trans *, struct xfs_inode *, | 143 | typedef 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); |
145 | typedef void (*xfs_dqstatvfs_t)(struct xfs_inode *, bhv_statvfs_t *); | ||
146 | typedef int (*xfs_dqsync_t)(struct xfs_mount *, int flags); | ||
147 | typedef int (*xfs_quotactl_t)(struct xfs_mount *, int, int, xfs_caddr_t); | ||
145 | 148 | ||
146 | typedef struct xfs_qmops { | 149 | typedef 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 | ||
650 | extern int xfs_dmops_get(struct xfs_mount *, struct xfs_mount_args *); | 662 | extern int xfs_dmops_get(struct xfs_mount *, struct xfs_mount_args *); |
651 | extern void xfs_dmops_put(struct xfs_mount *); | 663 | extern void xfs_dmops_put(struct xfs_mount *); |
664 | extern int xfs_qmops_get(struct xfs_mount *, struct xfs_mount_args *); | ||
665 | extern void xfs_qmops_put(struct xfs_mount *); | ||
652 | 666 | ||
653 | extern struct xfs_dmops xfs_dmcore_xfs; | 667 | extern struct xfs_dmops xfs_dmcore_xfs; |
654 | extern struct xfs_qmops xfs_qmcore_stub; | ||
655 | extern struct xfs_ioops xfs_iocore_xfs; | 668 | extern struct xfs_ioops xfs_iocore_xfs; |
656 | 669 | ||
657 | extern int xfs_init(void); | 670 | extern 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 | ||
32 | STATIC struct xfs_dquot * | 34 | STATIC struct xfs_dquot * |
33 | xfs_dqvopchown_default( | 35 | xfs_dqvopchown_default( |
@@ -110,7 +112,7 @@ xfs_noquota_init( | |||
110 | return error; | 112 | return error; |
111 | } | 113 | } |
112 | 114 | ||
113 | xfs_qmops_t xfs_qmcore_stub = { | 115 | static 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 | |||
134 | int | ||
135 | xfs_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 | |||
158 | void | ||
159 | xfs_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 { | |||
364 | extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *); | 364 | extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *); |
365 | extern int xfs_mount_reset_sbqflags(struct xfs_mount *); | 365 | extern int xfs_mount_reset_sbqflags(struct xfs_mount *); |
366 | 366 | ||
367 | extern struct bhv_module_vfsops xfs_qmops; | 367 | extern 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); |
557 | error0: | 574 | error0: |
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 | ||