diff options
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/quota/xfs_qm_bhv.c | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c index 6838b36d95a9..181dd90b29ce 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 |
@@ -185,6 +185,61 @@ xfs_qm_mount( | |||
185 | return error; | 185 | return error; |
186 | } | 186 | } |
187 | 187 | ||
188 | /* | ||
189 | * Directory tree accounting is implemented using project quotas, where | ||
190 | * the project identifier is inherited from parent directories. | ||
191 | * A statvfs (df, etc.) of a directory that is using project quota should | ||
192 | * return a statvfs of the project, not the entire filesystem. | ||
193 | * This makes such trees appear as if they are filesystems in themselves. | ||
194 | */ | ||
195 | STATIC int | ||
196 | xfs_qm_statvfs( | ||
197 | struct bhv_desc *bhv, | ||
198 | xfs_statfs_t *statp, | ||
199 | struct vnode *vnode) | ||
200 | { | ||
201 | xfs_mount_t *mp; | ||
202 | xfs_inode_t *ip; | ||
203 | xfs_dquot_t *dqp; | ||
204 | xfs_disk_dquot_t *dp; | ||
205 | __uint64_t limit; | ||
206 | int error; | ||
207 | |||
208 | error = PVFS_STATVFS(BHV_NEXT(bhv), statp, vnode); | ||
209 | if (error || !vnode) | ||
210 | return error; | ||
211 | |||
212 | mp = XFS_BHVTOM(bhv); | ||
213 | ip = xfs_vtoi(vnode); | ||
214 | |||
215 | if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)) | ||
216 | return 0; | ||
217 | if (!(mp->m_qflags & XFS_PQUOTA_ACCT)) | ||
218 | return 0; | ||
219 | if (!(mp->m_qflags & XFS_OQUOTA_ENFD)) | ||
220 | return 0; | ||
221 | |||
222 | if (xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp)) | ||
223 | return 0; | ||
224 | dp = &dqp->q_core; | ||
225 | |||
226 | limit = dp->d_blk_softlimit ? dp->d_blk_softlimit : dp->d_blk_hardlimit; | ||
227 | if (limit && statp->f_blocks > limit) { | ||
228 | statp->f_blocks = limit; | ||
229 | statp->f_bfree = (statp->f_blocks > dp->d_bcount) ? | ||
230 | (statp->f_blocks - dp->d_bcount) : 0; | ||
231 | } | ||
232 | limit = dp->d_ino_softlimit ? dp->d_ino_softlimit : dp->d_ino_hardlimit; | ||
233 | if (limit && statp->f_files > limit) { | ||
234 | statp->f_files = limit; | ||
235 | statp->f_ffree = (statp->f_files > dp->d_icount) ? | ||
236 | (statp->f_ffree - dp->d_icount) : 0; | ||
237 | } | ||
238 | |||
239 | xfs_qm_dqput(dqp); | ||
240 | return 0; | ||
241 | } | ||
242 | |||
188 | STATIC int | 243 | STATIC int |
189 | xfs_qm_syncall( | 244 | xfs_qm_syncall( |
190 | struct bhv_desc *bhv, | 245 | struct bhv_desc *bhv, |
@@ -351,6 +406,7 @@ struct bhv_vfsops xfs_qmops = { { | |||
351 | .vfs_parseargs = xfs_qm_parseargs, | 406 | .vfs_parseargs = xfs_qm_parseargs, |
352 | .vfs_showargs = xfs_qm_showargs, | 407 | .vfs_showargs = xfs_qm_showargs, |
353 | .vfs_mount = xfs_qm_mount, | 408 | .vfs_mount = xfs_qm_mount, |
409 | .vfs_statvfs = xfs_qm_statvfs, | ||
354 | .vfs_sync = xfs_qm_syncall, | 410 | .vfs_sync = xfs_qm_syncall, |
355 | .vfs_quotactl = xfs_qm_quotactl, }, | 411 | .vfs_quotactl = xfs_qm_quotactl, }, |
356 | }; | 412 | }; |