xfs: remove direct calls to _qm_dqread

The quota initialization code needs an "uncached" variant of _dqget to
read in default quota limits and timers before the dquot cache is fully
set up.  We've already split up _dqget into its component pieces so
create a fourth variant to address this need, and make dqread internal
to xfs_dquot.c again.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
Darrick J. Wong 2018-05-04 15:30:23 -07:00
parent d63192c890
commit 114e73ccfa
3 changed files with 39 additions and 15 deletions

View File

@ -586,7 +586,7 @@ err:
* *
* If XFS_QMOPT_DQALLOC is set, allocate a dquot on disk if it needed. * If XFS_QMOPT_DQALLOC is set, allocate a dquot on disk if it needed.
*/ */
int static int
xfs_qm_dqread( xfs_qm_dqread(
struct xfs_mount *mp, struct xfs_mount *mp,
xfs_dqid_t id, xfs_dqid_t id,
@ -832,6 +832,28 @@ restart:
return 0; return 0;
} }
/*
* Given a dquot id and type, read and initialize a dquot from the on-disk
* metadata. This function is only for use during quota initialization so
* it ignores the dquot cache assuming that the dquot shrinker isn't set up.
* The caller is responsible for _qm_dqdestroy'ing the returned dquot.
*/
int
xfs_qm_dqget_uncached(
struct xfs_mount *mp,
xfs_dqid_t id,
uint type,
struct xfs_dquot **dqpp)
{
int error;
error = xfs_qm_dqget_checks(mp, type);
if (error)
return error;
return xfs_qm_dqread(mp, id, type, 0, dqpp);
}
/* Return the quota id for a given inode and type. */ /* Return the quota id for a given inode and type. */
xfs_dqid_t xfs_dqid_t
xfs_qm_id_for_quotatype( xfs_qm_id_for_quotatype(

View File

@ -160,8 +160,6 @@ static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp)
#define XFS_QM_ISPDQ(dqp) ((dqp)->dq_flags & XFS_DQ_PROJ) #define XFS_QM_ISPDQ(dqp) ((dqp)->dq_flags & XFS_DQ_PROJ)
#define XFS_QM_ISGDQ(dqp) ((dqp)->dq_flags & XFS_DQ_GROUP) #define XFS_QM_ISGDQ(dqp) ((dqp)->dq_flags & XFS_DQ_GROUP)
extern int xfs_qm_dqread(struct xfs_mount *, xfs_dqid_t, uint,
uint, struct xfs_dquot **);
extern void xfs_qm_dqdestroy(xfs_dquot_t *); extern void xfs_qm_dqdestroy(xfs_dquot_t *);
extern int xfs_qm_dqflush(struct xfs_dquot *, struct xfs_buf **); extern int xfs_qm_dqflush(struct xfs_dquot *, struct xfs_buf **);
extern void xfs_qm_dqunpin_wait(xfs_dquot_t *); extern void xfs_qm_dqunpin_wait(xfs_dquot_t *);
@ -179,6 +177,9 @@ extern int xfs_qm_dqget_inode(struct xfs_inode *ip, uint type,
struct xfs_dquot **dqpp); struct xfs_dquot **dqpp);
extern int xfs_qm_dqget_next(struct xfs_mount *mp, xfs_dqid_t id, extern int xfs_qm_dqget_next(struct xfs_mount *mp, xfs_dqid_t id,
uint type, struct xfs_dquot **dqpp); uint type, struct xfs_dquot **dqpp);
extern int xfs_qm_dqget_uncached(struct xfs_mount *mp,
xfs_dqid_t id, uint type,
struct xfs_dquot **dqpp);
extern void xfs_qm_dqput(xfs_dquot_t *); extern void xfs_qm_dqput(xfs_dquot_t *);
extern void xfs_dqlock2(struct xfs_dquot *, struct xfs_dquot *); extern void xfs_dqlock2(struct xfs_dquot *, struct xfs_dquot *);

View File

@ -563,8 +563,7 @@ xfs_qm_set_defquota(
struct xfs_def_quota *defq; struct xfs_def_quota *defq;
int error; int error;
error = xfs_qm_dqread(mp, 0, type, 0, &dqp); error = xfs_qm_dqget_uncached(mp, 0, type, &dqp);
if (!error) { if (!error) {
xfs_disk_dquot_t *ddqp = &dqp->q_core; xfs_disk_dquot_t *ddqp = &dqp->q_core;
@ -590,11 +589,12 @@ xfs_qm_set_defquota(
*/ */
STATIC int STATIC int
xfs_qm_init_quotainfo( xfs_qm_init_quotainfo(
xfs_mount_t *mp) struct xfs_mount *mp)
{ {
xfs_quotainfo_t *qinf; struct xfs_quotainfo *qinf;
int error; struct xfs_dquot *dqp;
xfs_dquot_t *dqp; uint type;
int error;
ASSERT(XFS_IS_QUOTA_RUNNING(mp)); ASSERT(XFS_IS_QUOTA_RUNNING(mp));
@ -637,12 +637,13 @@ xfs_qm_init_quotainfo(
* user/group/proj quota types, otherwise a default value is used. * user/group/proj quota types, otherwise a default value is used.
* This should be split into different fields per quota type. * This should be split into different fields per quota type.
*/ */
error = xfs_qm_dqread(mp, 0, if (XFS_IS_UQUOTA_RUNNING(mp))
XFS_IS_UQUOTA_RUNNING(mp) ? XFS_DQ_USER : type = XFS_DQ_USER;
(XFS_IS_GQUOTA_RUNNING(mp) ? XFS_DQ_GROUP : else if (XFS_IS_GQUOTA_RUNNING(mp))
XFS_DQ_PROJ), type = XFS_DQ_GROUP;
0, &dqp); else
type = XFS_DQ_PROJ;
error = xfs_qm_dqget_uncached(mp, 0, type, &dqp);
if (!error) { if (!error) {
xfs_disk_dquot_t *ddqp = &dqp->q_core; xfs_disk_dquot_t *ddqp = &dqp->q_core;