@ -834,6 +834,36 @@ xfs_qm_qino_alloc(
int error ;
int committed ;
* ip = NULL ;
/*
* With superblock that doesn ' t have separate pquotino , we
* share an inode between gquota and pquota . If the on - disk
* superblock has GQUOTA and the filesystem is now mounted
* with PQUOTA , just use sb_gquotino for sb_pquotino and
* vice - versa .
*/
if ( ! xfs_sb_version_has_pquotino ( & mp - > m_sb ) & &
( flags & ( XFS_QMOPT_PQUOTA | XFS_QMOPT_GQUOTA ) ) ) {
xfs_ino_t ino = NULLFSINO ;
if ( ( flags & XFS_QMOPT_PQUOTA ) & &
( mp - > m_sb . sb_gquotino ! = NULLFSINO ) ) {
ino = mp - > m_sb . sb_gquotino ;
ASSERT ( mp - > m_sb . sb_pquotino = = NULLFSINO ) ;
} else if ( ( flags & XFS_QMOPT_GQUOTA ) & &
( mp - > m_sb . sb_pquotino ! = NULLFSINO ) ) {
ino = mp - > m_sb . sb_pquotino ;
ASSERT ( mp - > m_sb . sb_gquotino = = NULLFSINO ) ;
}
if ( ino ! = NULLFSINO ) {
error = xfs_iget ( mp , NULL , ino , 0 , 0 , ip ) ;
if ( error )
return error ;
mp - > m_sb . sb_gquotino = NULLFSINO ;
mp - > m_sb . sb_pquotino = NULLFSINO ;
}
}
tp = xfs_trans_alloc ( mp , XFS_TRANS_QM_QINOCREATE ) ;
if ( ( error = xfs_trans_reserve ( tp ,
XFS_QM_QINOCREATE_SPACE_RES ( mp ) ,
@ -844,11 +874,14 @@ xfs_qm_qino_alloc(
return error ;
}
error = xfs_dir_ialloc ( & tp , NULL , S_IFREG , 1 , 0 , 0 , 1 , ip , & committed ) ;
if ( error ) {
xfs_trans_cancel ( tp , XFS_TRANS_RELEASE_LOG_RES |
XFS_TRANS_ABORT ) ;
return error ;
if ( ! * ip ) {
error = xfs_dir_ialloc ( & tp , NULL , S_IFREG , 1 , 0 , 0 , 1 , ip ,
& committed ) ;
if ( error ) {
xfs_trans_cancel ( tp , XFS_TRANS_RELEASE_LOG_RES |
XFS_TRANS_ABORT ) ;
return error ;
}
}
/*
@ -860,21 +893,25 @@ xfs_qm_qino_alloc(
if ( flags & XFS_QMOPT_SBVERSION ) {
ASSERT ( ! xfs_sb_version_hasquota ( & mp - > m_sb ) ) ;
ASSERT ( ( sbfields & ( XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
XFS_SB_GQUOTINO | XFS_SB_QFLAGS ) ) = =
( XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
XFS_SB_GQUOTINO | XFS_SB_QFLAGS ) ) ;
XFS_SB_GQUOTINO | XFS_SB_PQUOTINO | XFS_SB_QFLAGS ) ) = =
( XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
XFS_SB_GQUOTINO | XFS_SB_PQUOTINO |
XFS_SB_QFLAGS ) ) ;
xfs_sb_version_addquota ( & mp - > m_sb ) ;
mp - > m_sb . sb_uquotino = NULLFSINO ;
mp - > m_sb . sb_gquotino = NULLFSINO ;
mp - > m_sb . sb_pquotino = NULLFSINO ;
/* qflags will get updated _after_ quotacheck */
mp - > m_sb . sb_qflags = 0 ;
/* qflags will get updated fully _after_ quotacheck */
mp - > m_sb . sb_qflags = mp - > m_qflags & XFS_ALL_QUOTA_ACCT ;
}
if ( flags & XFS_QMOPT_UQUOTA )
mp - > m_sb . sb_uquotino = ( * ip ) - > i_ino ;
else
else if ( flags & XFS_QMOPT_GQUOTA )
mp - > m_sb . sb_gquotino = ( * ip ) - > i_ino ;
else
mp - > m_sb . sb_pquotino = ( * ip ) - > i_ino ;
spin_unlock ( & mp - > m_sb_lock ) ;
xfs_mod_sb ( tp , sbfields ) ;
@ -1484,11 +1521,10 @@ xfs_qm_init_quotainos(
if ( error )
goto error_rele ;
}
/* XXX: Use gquotino for now */
if ( XFS_IS_PQUOTA_ON ( mp ) & &
mp - > m_sb . sb_g quotino ! = NULLFSINO ) {
ASSERT ( mp - > m_sb . sb_g quotino > 0 ) ;
error = xfs_iget ( mp , NULL , mp - > m_sb . sb_g quotino ,
mp - > m_sb . sb_p quotino ! = NULLFSINO ) {
ASSERT ( mp - > m_sb . sb_p quotino > 0 ) ;
error = xfs_iget ( mp , NULL , mp - > m_sb . sb_p quotino ,
0 , 0 , & pip ) ;
if ( error )
goto error_rele ;
@ -1496,7 +1532,8 @@ xfs_qm_init_quotainos(
} else {
flags | = XFS_QMOPT_SBVERSION ;
sbflags | = ( XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
XFS_SB_GQUOTINO | XFS_SB_QFLAGS ) ;
XFS_SB_GQUOTINO | XFS_SB_PQUOTINO |
XFS_SB_QFLAGS ) ;
}
/*
@ -1524,9 +1561,8 @@ xfs_qm_init_quotainos(
flags & = ~ XFS_QMOPT_SBVERSION ;
}
if ( XFS_IS_PQUOTA_ON ( mp ) & & pip = = NULL ) {
/* XXX: Use XFS_SB_GQUOTINO for now */
error = xfs_qm_qino_alloc ( mp , & pip ,
sbflags | XFS_SB_G QUOTINO ,
sbflags | XFS_SB_P QUOTINO ,
flags | XFS_QMOPT_PQUOTA ) ;
if ( error )
goto error_rele ;