if (mp->m_sb.sb_inoalignmt)
sbversion |= XFS_SB_VERSION_ALIGNBIT;
if ((mp->m_sb.sb_uquotino && mp->m_sb.sb_uquotino != NULLFSINO) ||
- (mp->m_sb.sb_gquotino && mp->m_sb.sb_gquotino != NULLFSINO))
+ (mp->m_sb.sb_gquotino && mp->m_sb.sb_gquotino != NULLFSINO) ||
+ (mp->m_sb.sb_pquotino && mp->m_sb.sb_pquotino != NULLFSINO))
sbversion |= XFS_SB_VERSION_QUOTABIT;
quota_init();
return 1;
addlink_inode(id);
}
else if (id->ino == mp->m_sb.sb_uquotino ||
- id->ino == mp->m_sb.sb_gquotino) {
+ id->ino == mp->m_sb.sb_gquotino ||
+ id->ino == mp->m_sb.sb_pquotino) {
type = DBM_QUOTA;
blkmap = blkmap_alloc(idic.di_nextents);
addlink_inode(id);
(mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) &&
(mp->m_sb.sb_qflags & XFS_GQUOTA_CHKD))
process_quota(IS_GROUP_QUOTA, id, blkmap);
- else if (id->ino == mp->m_sb.sb_gquotino &&
+ else if (id->ino == mp->m_sb.sb_pquotino &&
(mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) &&
(mp->m_sb.sb_qflags & XFS_PQUOTA_CHKD))
process_quota(IS_PROJECT_QUOTA, id, blkmap);
mp->m_sb.sb_gquotino != NULLFSINO &&
(mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) &&
(mp->m_sb.sb_qflags & XFS_GQUOTA_CHKD);
- qpdo = mp->m_sb.sb_gquotino != 0 &&
- mp->m_sb.sb_gquotino != NULLFSINO &&
+ qpdo = mp->m_sb.sb_pquotino != 0 &&
+ mp->m_sb.sb_pquotino != NULLFSINO &&
(mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) &&
(mp->m_sb.sb_qflags & XFS_PQUOTA_CHKD);
if (qudo)
dbprintf(_("dquot command requires one %s id argument\n"), s);
return 0;
}
- ino = (dogrp || doprj) ? mp->m_sb.sb_gquotino : mp->m_sb.sb_uquotino;
- if (ino == 0 || ino == NULLFSINO ||
- (dogrp && (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT)) ||
- (doprj && (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT))) {
+ ino = mp->m_sb.sb_uquotino;
+ if (doprj)
+ ino = mp->m_sb.sb_pquotino;
+ else if (dogrp)
+ ino = mp->m_sb.sb_gquotino;
+
+ if (ino == 0 || ino == NULLFSINO) {
dbprintf(_("no %s quota inode present\n"), s);
return 0;
}
skipd = 1;
else if (!qflag &&
(ino == mp->m_sb.sb_uquotino ||
- ino == mp->m_sb.sb_gquotino))
+ ino == mp->m_sb.sb_gquotino ||
+ ino == mp->m_sb.sb_pquotino))
skipd = 1;
else
skipd = !fflag;
else if (iocur_top->ino == mp->m_sb.sb_rsumino)
return TYP_RTSUMMARY;
else if (iocur_top->ino == mp->m_sb.sb_uquotino ||
- iocur_top->ino == mp->m_sb.sb_gquotino)
+ iocur_top->ino == mp->m_sb.sb_gquotino ||
+ iocur_top->ino == mp->m_sb.sb_pquotino)
return TYP_DQBLK;
else
return TYP_DATA;
if (!copy_ino(mp->m_sb.sb_uquotino, TYP_DQBLK))
return 0;
- return copy_ino(mp->m_sb.sb_gquotino, TYP_DQBLK);
+ if (!copy_ino(mp->m_sb.sb_gquotino, TYP_DQBLK))
+ return 0;
+
+ return copy_ino(mp->m_sb.sb_pquotino, TYP_DQBLK);
}
static int
return (sbp->sb_features_log_incompat & feature) != 0;
}
+static inline int xfs_sb_version_has_pquotino(xfs_sb_t *sbp)
+{
+ return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5;
+}
+
/*
* end of superblock version macros
*/
static void
xfs_sb_quota_from_disk(struct xfs_sb *sbp)
{
+ /*
+ * We need to do these manipilations only if we are working
+ * with an older version of on-disk superblock.
+ */
+ if (xfs_sb_version_has_pquotino(sbp))
+ return;
+
if (sbp->sb_qflags & XFS_OQUOTA_ENFD)
sbp->sb_qflags |= (sbp->sb_qflags & XFS_PQUOTA_ACCT) ?
XFS_PQUOTA_ENFD : XFS_GQUOTA_ENFD;
sbp->sb_qflags |= (sbp->sb_qflags & XFS_PQUOTA_ACCT) ?
XFS_PQUOTA_CHKD : XFS_GQUOTA_CHKD;
sbp->sb_qflags &= ~(XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD);
+
+ if (sbp->sb_qflags & XFS_PQUOTA_ACCT) {
+ /*
+ * In older version of superblock, on-disk superblock only
+ * has sb_gquotino, and in-core superblock has both sb_gquotino
+ * and sb_pquotino. But, only one of them is supported at any
+ * point of time. So, if PQUOTA is set in disk superblock,
+ * copy over sb_gquotino to sb_pquotino.
+ */
+ sbp->sb_pquotino = sbp->sb_gquotino;
+ sbp->sb_gquotino = NULLFSINO;
+ }
}
static inline void
{
__uint16_t qflags = from->sb_qflags;
+ /*
+ * We need to do these manipilations only if we are working
+ * with an older version of on-disk superblock.
+ */
+ if (xfs_sb_version_has_pquotino(from))
+ return;
+
if (*fields & XFS_SB_QFLAGS) {
/*
* The in-core version of sb_qflags do not have
to->sb_qflags = cpu_to_be16(qflags);
*fields &= ~XFS_SB_QFLAGS;
}
+
+ /*
+ * GQUOTINO and PQUOTINO cannot be used together in versions
+ * of superblock that do not have pquotino. from->sb_flags
+ * tells us which quota is active and should be copied to
+ * disk.
+ */
+ if ((*fields & XFS_SB_GQUOTINO) &&
+ (from->sb_qflags & XFS_GQUOTA_ACCT))
+ to->sb_gquotino = cpu_to_be64(from->sb_gquotino);
+ else if ((*fields & XFS_SB_PQUOTINO) &&
+ (from->sb_qflags & XFS_PQUOTA_ACCT))
+ to->sb_gquotino = cpu_to_be64(from->sb_pquotino);
+
+ *fields &= ~(XFS_SB_PQUOTINO | XFS_SB_GQUOTINO);
}
/*
return;
xfs_sb_quota_to_disk(to, from, &fields);
+
while (fields) {
f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
first = xfs_sb_info[f].offset;
sbp->sb_fdblocks = dblocks - agcount * XFS_PREALLOC_BLOCKS(mp) -
(loginternal ? logblocks : 0);
sbp->sb_frextents = 0; /* will do a free later */
- sbp->sb_uquotino = sbp->sb_gquotino = 0;
+ sbp->sb_uquotino = sbp->sb_gquotino = sbp->sb_pquotino = 0;
sbp->sb_qflags = 0;
sbp->sb_unit = dsunit;
sbp->sb_width = dswidth;
rval |= XR_AG_SB_SEC;
}
+ if (sb->sb_inprogress == 1 && sb->sb_pquotino) {
+ if (!no_modify)
+ sb->sb_pquotino = 0;
+ if (sb->sb_versionnum & XR_PART_SECSB_VNMASK || !do_bzero) {
+ rval |= XR_AG_SB;
+ do_warn(
+ _("non-null project quota inode field in superblock %d\n"),
+ i);
+
+ } else
+ rval |= XR_AG_SB_SEC;
+ }
+
if (sb->sb_inprogress == 1 && sb->sb_qflags) {
if (!no_modify)
sb->sb_qflags = 0;
}
return 0;
}
+ if (lino == mp->m_sb.sb_pquotino) {
+ if (*type != XR_INO_DATA) {
+ do_warn(_("project quota inode %" PRIu64 " has bad type 0x%x\n"),
+ lino, dinode_fmt(dinoc));
+ mp->m_sb.sb_pquotino = NULLFSINO;
+ return 1;
+ }
+ return 0;
+ }
if (lino == mp->m_sb.sb_rsumino) {
if (*type != XR_INO_RTSUM) {
do_warn(
} else if (lino == mp->m_sb.sb_gquotino) {
junkit = 1;
junkreason = _("group quota");
+ } else if (lino == mp->m_sb.sb_pquotino) {
+ junkit = 1;
+ junkreason = _("project quota");
} else if ((irec_p = find_inode_rec(mp,
XFS_INO_TO_AGNO(mp, lino),
XFS_INO_TO_AGINO(mp, lino))) != NULL) {
clearreason = _("user quota");
} else if (ent_ino == mp->m_sb.sb_gquotino) {
clearreason = _("group quota");
+ } else if (ent_ino == mp->m_sb.sb_pquotino) {
+ clearreason = _("project quota");
} else {
irec_p = find_inode_rec(mp,
XFS_INO_TO_AGNO(mp, ent_ino),
EXTERN int lost_quotas;
EXTERN int have_uquotino;
EXTERN int have_gquotino;
+EXTERN int have_pquotino;
EXTERN int lost_uquotino;
EXTERN int lost_gquotino;
EXTERN int lost_pquotino;
if (irec == NULL || is_inode_free(irec,
mp->m_sb.sb_gquotino - irec->ino_startnum)) {
mp->m_sb.sb_gquotino = NULLFSINO;
- if (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT)
- lost_gquotino = 1;
- else
- lost_pquotino = 1;
+ lost_gquotino = 1;
} else
- lost_gquotino = lost_pquotino = 0;
+ lost_gquotino = 0;
+ }
+
+ if (mp->m_sb.sb_pquotino != NULLFSINO && mp->m_sb.sb_pquotino != 0) {
+ if (verify_inum(mp, mp->m_sb.sb_pquotino))
+ irec = NULL;
+ else
+ irec = find_inode_rec(mp,
+ XFS_INO_TO_AGNO(mp, mp->m_sb.sb_pquotino),
+ XFS_INO_TO_AGINO(mp, mp->m_sb.sb_pquotino));
+
+ if (irec == NULL || is_inode_free(irec,
+ mp->m_sb.sb_pquotino - irec->ino_startnum)) {
+ mp->m_sb.sb_pquotino = NULLFSINO;
+ lost_pquotino = 1;
+ } else
+ lost_pquotino = 0;
}
}
if (fs_quotas &&
(mp->m_sb.sb_uquotino == NULLFSINO || mp->m_sb.sb_uquotino == 0) &&
- (mp->m_sb.sb_gquotino == NULLFSINO || mp->m_sb.sb_gquotino == 0)) {
+ (mp->m_sb.sb_gquotino == NULLFSINO || mp->m_sb.sb_gquotino == 0) &&
+ (mp->m_sb.sb_pquotino == NULLFSINO || mp->m_sb.sb_pquotino == 0)) {
lost_quotas = 1;
fs_quotas = 0;
} else if (!verify_inum(mp, mp->m_sb.sb_uquotino) &&
- !verify_inum(mp, mp->m_sb.sb_gquotino)) {
+ !verify_inum(mp, mp->m_sb.sb_gquotino) &&
+ !verify_inum(mp, mp->m_sb.sb_pquotino)) {
fs_quotas = 1;
}
}
- irec->ino_startnum;
add_inode_reached(irec, offset);
}
+ if (mp->m_sb.sb_pquotino
+ && mp->m_sb.sb_pquotino != NULLFSINO) {
+ irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp,
+ mp->m_sb.sb_pquotino),
+ XFS_INO_TO_AGINO(mp, mp->m_sb.sb_pquotino));
+ offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_pquotino)
+ - irec->ino_startnum;
+ add_inode_reached(irec, offset);
+ }
}
}
xfs_ino_t rsumino;
xfs_ino_t uquotino;
xfs_ino_t gquotino;
+ xfs_ino_t pquotino;
__uint16_t versionnum;
rootino = dest->sb_rootino;
rsumino = dest->sb_rsumino;
uquotino = dest->sb_uquotino;
gquotino = dest->sb_gquotino;
+ pquotino = dest->sb_pquotino;
versionnum = dest->sb_versionnum;
dest->sb_rsumino = rsumino;
dest->sb_uquotino = uquotino;
dest->sb_gquotino = gquotino;
+ dest->sb_pquotino = pquotino;
dest->sb_versionnum = versionnum;
fs_has_extflgbit = 0;
have_uquotino = 0;
have_gquotino = 0;
+ have_pquotino = 0;
issue_warning = 0;
/*
if (sb->sb_gquotino != 0 &&
sb->sb_gquotino != NULLFSINO)
have_gquotino = 1;
+
+ if (sb->sb_pquotino != 0 &&
+ sb->sb_pquotino != NULLFSINO)
+ have_pquotino = 1;
}
}
_("Inode allocation btrees are too corrupted, skipping phases 6 and 7\n"));
}
- if (lost_quotas && !have_uquotino && !have_gquotino) {
+ if (lost_quotas && !have_uquotino && !have_gquotino && !have_pquotino) {
if (!no_modify) {
do_warn(
_("Warning: no quota inodes were found. Quotas disabled.\n"));