diff options
Diffstat (limited to 'fs/xfs/quota/xfs_qm_bhv.c')
-rw-r--r-- | fs/xfs/quota/xfs_qm_bhv.c | 81 |
1 files changed, 65 insertions, 16 deletions
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c index 6838b36d95a9..e95e99f7168f 100644 --- a/fs/xfs/quota/xfs_qm_bhv.c +++ b/fs/xfs/quota/xfs_qm_bhv.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -24,7 +24,6 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_alloc.h" | 28 | #include "xfs_alloc.h" |
30 | #include "xfs_dmapi.h" | 29 | #include "xfs_dmapi.h" |
@@ -33,7 +32,6 @@ | |||
33 | #include "xfs_bmap_btree.h" | 32 | #include "xfs_bmap_btree.h" |
34 | #include "xfs_alloc_btree.h" | 33 | #include "xfs_alloc_btree.h" |
35 | #include "xfs_ialloc_btree.h" | 34 | #include "xfs_ialloc_btree.h" |
36 | #include "xfs_dir_sf.h" | ||
37 | #include "xfs_dir2_sf.h" | 35 | #include "xfs_dir2_sf.h" |
38 | #include "xfs_attr_sf.h" | 36 | #include "xfs_attr_sf.h" |
39 | #include "xfs_dinode.h" | 37 | #include "xfs_dinode.h" |
@@ -129,7 +127,7 @@ xfs_qm_parseargs( | |||
129 | return XFS_ERROR(EINVAL); | 127 | return XFS_ERROR(EINVAL); |
130 | } | 128 | } |
131 | 129 | ||
132 | PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error); | 130 | error = bhv_next_vfs_parseargs(BHV_NEXT(bhv), options, args, update); |
133 | if (!error && !referenced) | 131 | if (!error && !referenced) |
134 | bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM); | 132 | bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM); |
135 | return error; | 133 | return error; |
@@ -140,9 +138,8 @@ xfs_qm_showargs( | |||
140 | struct bhv_desc *bhv, | 138 | struct bhv_desc *bhv, |
141 | struct seq_file *m) | 139 | struct seq_file *m) |
142 | { | 140 | { |
143 | struct vfs *vfsp = bhvtovfs(bhv); | 141 | struct bhv_vfs *vfsp = bhvtovfs(bhv); |
144 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); | 142 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); |
145 | int error; | ||
146 | 143 | ||
147 | if (mp->m_qflags & XFS_UQUOTA_ACCT) { | 144 | if (mp->m_qflags & XFS_UQUOTA_ACCT) { |
148 | (mp->m_qflags & XFS_UQUOTA_ENFD) ? | 145 | (mp->m_qflags & XFS_UQUOTA_ENFD) ? |
@@ -165,8 +162,7 @@ xfs_qm_showargs( | |||
165 | if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) | 162 | if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) |
166 | seq_puts(m, "," MNTOPT_NOQUOTA); | 163 | seq_puts(m, "," MNTOPT_NOQUOTA); |
167 | 164 | ||
168 | PVFS_SHOWARGS(BHV_NEXT(bhv), m, error); | 165 | return bhv_next_vfs_showargs(BHV_NEXT(bhv), m); |
169 | return error; | ||
170 | } | 166 | } |
171 | 167 | ||
172 | STATIC int | 168 | STATIC int |
@@ -175,14 +171,67 @@ xfs_qm_mount( | |||
175 | struct xfs_mount_args *args, | 171 | struct xfs_mount_args *args, |
176 | struct cred *cr) | 172 | struct cred *cr) |
177 | { | 173 | { |
178 | struct vfs *vfsp = bhvtovfs(bhv); | 174 | struct bhv_vfs *vfsp = bhvtovfs(bhv); |
179 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); | 175 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); |
180 | int error; | ||
181 | 176 | ||
182 | if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA)) | 177 | if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA)) |
183 | xfs_qm_mount_quotainit(mp, args->flags); | 178 | xfs_qm_mount_quotainit(mp, args->flags); |
184 | PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error); | 179 | return bhv_next_vfs_mount(BHV_NEXT(bhv), args, cr); |
185 | return error; | 180 | } |
181 | |||
182 | /* | ||
183 | * Directory tree accounting is implemented using project quotas, where | ||
184 | * the project identifier is inherited from parent directories. | ||
185 | * A statvfs (df, etc.) of a directory that is using project quota should | ||
186 | * return a statvfs of the project, not the entire filesystem. | ||
187 | * This makes such trees appear as if they are filesystems in themselves. | ||
188 | */ | ||
189 | STATIC int | ||
190 | xfs_qm_statvfs( | ||
191 | struct bhv_desc *bhv, | ||
192 | bhv_statvfs_t *statp, | ||
193 | struct bhv_vnode *vnode) | ||
194 | { | ||
195 | xfs_mount_t *mp; | ||
196 | xfs_inode_t *ip; | ||
197 | xfs_dquot_t *dqp; | ||
198 | xfs_disk_dquot_t *dp; | ||
199 | __uint64_t limit; | ||
200 | int error; | ||
201 | |||
202 | error = bhv_next_vfs_statvfs(BHV_NEXT(bhv), statp, vnode); | ||
203 | if (error || !vnode) | ||
204 | return error; | ||
205 | |||
206 | mp = XFS_BHVTOM(bhv); | ||
207 | ip = xfs_vtoi(vnode); | ||
208 | |||
209 | if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)) | ||
210 | return 0; | ||
211 | if (!(mp->m_qflags & XFS_PQUOTA_ACCT)) | ||
212 | return 0; | ||
213 | if (!(mp->m_qflags & XFS_OQUOTA_ENFD)) | ||
214 | return 0; | ||
215 | |||
216 | if (xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp)) | ||
217 | return 0; | ||
218 | dp = &dqp->q_core; | ||
219 | |||
220 | limit = dp->d_blk_softlimit ? dp->d_blk_softlimit : dp->d_blk_hardlimit; | ||
221 | if (limit && statp->f_blocks > limit) { | ||
222 | statp->f_blocks = limit; | ||
223 | statp->f_bfree = (statp->f_blocks > dp->d_bcount) ? | ||
224 | (statp->f_blocks - dp->d_bcount) : 0; | ||
225 | } | ||
226 | limit = dp->d_ino_softlimit ? dp->d_ino_softlimit : dp->d_ino_hardlimit; | ||
227 | if (limit && statp->f_files > limit) { | ||
228 | statp->f_files = limit; | ||
229 | statp->f_ffree = (statp->f_files > dp->d_icount) ? | ||
230 | (statp->f_ffree - dp->d_icount) : 0; | ||
231 | } | ||
232 | |||
233 | xfs_qm_dqput(dqp); | ||
234 | return 0; | ||
186 | } | 235 | } |
187 | 236 | ||
188 | STATIC int | 237 | STATIC int |
@@ -191,7 +240,7 @@ xfs_qm_syncall( | |||
191 | int flags, | 240 | int flags, |
192 | cred_t *credp) | 241 | cred_t *credp) |
193 | { | 242 | { |
194 | struct vfs *vfsp = bhvtovfs(bhv); | 243 | struct bhv_vfs *vfsp = bhvtovfs(bhv); |
195 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); | 244 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); |
196 | int error; | 245 | int error; |
197 | 246 | ||
@@ -210,8 +259,7 @@ xfs_qm_syncall( | |||
210 | } | 259 | } |
211 | } | 260 | } |
212 | } | 261 | } |
213 | PVFS_SYNC(BHV_NEXT(bhv), flags, credp, error); | 262 | return bhv_next_vfs_sync(BHV_NEXT(bhv), flags, credp); |
214 | return error; | ||
215 | } | 263 | } |
216 | 264 | ||
217 | STATIC int | 265 | STATIC int |
@@ -346,11 +394,12 @@ STATIC struct xfs_qmops xfs_qmcore_xfs = { | |||
346 | .xfs_dqtrxops = &xfs_trans_dquot_ops, | 394 | .xfs_dqtrxops = &xfs_trans_dquot_ops, |
347 | }; | 395 | }; |
348 | 396 | ||
349 | struct bhv_vfsops xfs_qmops = { { | 397 | struct bhv_module_vfsops xfs_qmops = { { |
350 | BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM), | 398 | BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM), |
351 | .vfs_parseargs = xfs_qm_parseargs, | 399 | .vfs_parseargs = xfs_qm_parseargs, |
352 | .vfs_showargs = xfs_qm_showargs, | 400 | .vfs_showargs = xfs_qm_showargs, |
353 | .vfs_mount = xfs_qm_mount, | 401 | .vfs_mount = xfs_qm_mount, |
402 | .vfs_statvfs = xfs_qm_statvfs, | ||
354 | .vfs_sync = xfs_qm_syncall, | 403 | .vfs_sync = xfs_qm_syncall, |
355 | .vfs_quotactl = xfs_qm_quotactl, }, | 404 | .vfs_quotactl = xfs_qm_quotactl, }, |
356 | }; | 405 | }; |