|
@@ -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_gquotino != NULLFSINO) {
|
|
|
- ASSERT(mp->m_sb.sb_gquotino > 0);
|
|
|
- error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
|
|
|
+ mp->m_sb.sb_pquotino != NULLFSINO) {
|
|
|
+ ASSERT(mp->m_sb.sb_pquotino > 0);
|
|
|
+ error = xfs_iget(mp, NULL, mp->m_sb.sb_pquotino,
|
|
|
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_GQUOTINO,
|
|
|
+ sbflags | XFS_SB_PQUOTINO,
|
|
|
flags | XFS_QMOPT_PQUOTA);
|
|
|
if (error)
|
|
|
goto error_rele;
|