2018-06-06 05:42:14 +03:00
// SPDX-License-Identifier: GPL-2.0
2005-04-17 02:20:36 +04:00
/*
2006-06-09 09:29:58 +04:00
* Copyright ( c ) 2000 - 2006 Silicon Graphics , Inc .
2005-11-02 06:59:41 +03:00
* All Rights Reserved .
2005-04-17 02:20:36 +04:00
*/
# include "xfs.h"
# include "xfs_fs.h"
2019-06-29 05:25:35 +03:00
# include "xfs_shared.h"
2013-08-12 14:49:26 +04:00
# include "xfs_format.h"
2013-10-23 03:50:10 +04:00
# include "xfs_log_format.h"
# include "xfs_trans_resv.h"
2005-04-17 02:20:36 +04:00
# include "xfs_quota.h"
# include "xfs_mount.h"
# include "xfs_inode.h"
2013-10-23 03:50:10 +04:00
# include "xfs_trans.h"
2005-04-17 02:20:36 +04:00
# include "xfs_qm.h"
2007-08-30 11:19:57 +04:00
STATIC void
xfs_fill_statvfs_from_dquot (
2008-11-28 06:23:36 +03:00
struct kstatfs * statp ,
2012-02-20 06:28:17 +04:00
struct xfs_dquot * dqp )
2006-06-09 09:29:58 +04:00
{
2017-06-16 21:00:05 +03:00
uint64_t limit ;
2006-06-09 09:29:58 +04:00
2020-07-14 20:37:31 +03:00
limit = dqp - > q_blk . softlimit ?
dqp - > q_blk . softlimit :
dqp - > q_blk . hardlimit ;
2006-06-09 09:29:58 +04:00
if ( limit & & statp - > f_blocks > limit ) {
statp - > f_blocks = limit ;
2010-01-21 14:17:20 +03:00
statp - > f_bfree = statp - > f_bavail =
2020-07-14 20:37:30 +03:00
( statp - > f_blocks > dqp - > q_blk . reserved ) ?
( statp - > f_blocks - dqp - > q_blk . reserved ) : 0 ;
2006-06-09 09:29:58 +04:00
}
2006-07-28 11:04:26 +04:00
2020-07-14 20:37:31 +03:00
limit = dqp - > q_ino . softlimit ?
dqp - > q_ino . softlimit :
dqp - > q_ino . hardlimit ;
2006-06-09 09:29:58 +04:00
if ( limit & & statp - > f_files > limit ) {
statp - > f_files = limit ;
2006-07-28 11:04:26 +04:00
statp - > f_ffree =
2020-07-14 20:37:30 +03:00
( statp - > f_files > dqp - > q_ino . reserved ) ?
( statp - > f_files - dqp - > q_ino . reserved ) : 0 ;
2006-06-09 09:29:58 +04:00
}
}
2007-08-30 11:19:57 +04:00
/*
* Directory tree accounting is implemented using project quotas , where
* the project identifier is inherited from parent directories .
* A statvfs ( df , etc . ) of a directory that is using project quota should
* return a statvfs of the project , not the entire filesystem .
* This makes such trees appear as if they are filesystems in themselves .
*/
2009-06-08 17:33:32 +04:00
void
2007-08-30 11:19:57 +04:00
xfs_qm_statvfs (
2019-11-13 04:04:02 +03:00
struct xfs_inode * ip ,
2008-11-28 06:23:36 +03:00
struct kstatfs * statp )
2005-04-17 02:20:36 +04:00
{
2019-11-13 04:04:02 +03:00
struct xfs_mount * mp = ip - > i_mount ;
struct xfs_dquot * dqp ;
2005-04-17 02:20:36 +04:00
2021-03-29 21:11:39 +03:00
if ( ! xfs_qm_dqget ( mp , ip - > i_projid , XFS_DQTYPE_PROJ , false , & dqp ) ) {
2012-02-20 06:28:17 +04:00
xfs_fill_statvfs_from_dquot ( statp , dqp ) ;
2007-08-30 11:19:57 +04:00
xfs_qm_dqput ( dqp ) ;
2005-04-17 02:20:36 +04:00
}
}
2009-06-08 17:33:32 +04:00
int
2005-04-17 02:20:36 +04:00
xfs_qm_newmount (
xfs_mount_t * mp ,
uint * needquotamount ,
uint * quotaflags )
{
uint quotaondisk ;
2005-06-21 09:38:48 +04:00
uint uquotaondisk = 0 , gquotaondisk = 0 , pquotaondisk = 0 ;
2005-04-17 02:20:36 +04:00
2021-08-19 04:46:37 +03:00
quotaondisk = xfs_has_quota ( mp ) & &
2005-06-21 09:38:48 +04:00
( mp - > m_sb . sb_qflags & XFS_ALL_QUOTA_ACCT ) ;
2005-04-17 02:20:36 +04:00
if ( quotaondisk ) {
uquotaondisk = mp - > m_sb . sb_qflags & XFS_UQUOTA_ACCT ;
2005-06-21 09:38:48 +04:00
pquotaondisk = mp - > m_sb . sb_qflags & XFS_PQUOTA_ACCT ;
2005-04-17 02:20:36 +04:00
gquotaondisk = mp - > m_sb . sb_qflags & XFS_GQUOTA_ACCT ;
}
/*
* If the device itself is read - only , we can ' t allow
* the user to change the state of quota on the mount -
* this would generate a transaction on the ro device ,
* which would lead to an I / O error and shutdown
*/
if ( ( ( uquotaondisk & & ! XFS_IS_UQUOTA_ON ( mp ) ) | |
( ! uquotaondisk & & XFS_IS_UQUOTA_ON ( mp ) ) | |
( gquotaondisk & & ! XFS_IS_GQUOTA_ON ( mp ) ) | |
2013-07-11 09:00:40 +04:00
( ! gquotaondisk & & XFS_IS_GQUOTA_ON ( mp ) ) | |
( pquotaondisk & & ! XFS_IS_PQUOTA_ON ( mp ) ) | |
( ! pquotaondisk & & XFS_IS_PQUOTA_ON ( mp ) ) ) & &
2005-04-17 02:20:36 +04:00
xfs_dev_is_read_only ( mp , " changing quota state " ) ) {
2011-03-07 02:08:35 +03:00
xfs_warn ( mp , " please mount with%s%s%s%s. " ,
2005-04-17 02:20:36 +04:00
( ! quotaondisk ? " out quota " : " " ) ,
( uquotaondisk ? " usrquota " : " " ) ,
2013-07-11 09:00:40 +04:00
( gquotaondisk ? " grpquota " : " " ) ,
( pquotaondisk ? " prjquota " : " " ) ) ;
2014-06-25 08:58:08 +04:00
return - EPERM ;
2005-04-17 02:20:36 +04:00
}
if ( XFS_IS_QUOTA_ON ( mp ) | | quotaondisk ) {
/*
* Call mount_quotas at this point only if we won ' t have to do
* a quotacheck .
*/
if ( quotaondisk & & ! XFS_QM_NEED_QUOTACHECK ( mp ) ) {
/*
2011-03-31 05:57:33 +04:00
* If an error occurred , qm_mount_quotas code
2005-04-17 02:20:36 +04:00
* has already disabled quotas . So , just finish
* mounting , and get on with the boring life
* without disk quotas .
*/
2008-08-13 10:49:32 +04:00
xfs_qm_mount_quotas ( mp ) ;
2005-04-17 02:20:36 +04:00
} else {
/*
* Clear the quota flags , but remember them . This
* is so that the quota code doesn ' t get invoked
* before we ' re ready . This can happen when an
* inode goes inactive and wants to free blocks ,
* or via xfs_log_mount_finish .
*/
2012-11-13 03:32:59 +04:00
* needquotamount = true ;
2005-04-17 02:20:36 +04:00
* quotaflags = mp - > m_qflags ;
mp - > m_qflags = 0 ;
}
}
return 0 ;
}