diff options
Diffstat (limited to 'fs')
| -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 | }; |
