Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4882c19d authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: split out dqget for inodes from regular dqget



There are two uses of dqget here -- one is to return the dquot for a
given type and id, and the other is to return the dquot for a given type
and inode.  Those are two separate things, so split them into two
smaller functions.

Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent c14cfcca
Loading
Loading
Loading
Loading
+104 −44
Original line number Original line Diff line number Diff line
@@ -790,35 +790,102 @@ xfs_qm_dqget_checks(
}
}


/*
/*
 * Given the file system, inode OR id, and type (UDQUOT/GDQUOT), return a
 * Given the file system, id, and type (UDQUOT/GDQUOT), return a a locked
 * a locked dquot, doing an allocation (if requested) as needed.
 * dquot, doing an allocation (if requested) as needed.
 * When both an inode and an id are given, the inode's id takes precedence.
 * That is, if the id changes while we don't hold the ilock inside this
 * function, the new dquot is returned, not necessarily the one requested
 * in the id argument.
 */
 */
int
int
xfs_qm_dqget(
xfs_qm_dqget(
	xfs_mount_t	*mp,
	struct xfs_mount	*mp,
	xfs_inode_t	*ip,	  /* locked inode (optional) */
	xfs_dqid_t		id,
	xfs_dqid_t	id,	  /* uid/projid/gid depending on type */
	uint			type,
	uint		type,	  /* XFS_DQ_USER/XFS_DQ_PROJ/XFS_DQ_GROUP */
	uint			flags,	  /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */
	uint			flags,	  /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */
	xfs_dquot_t	**O_dqpp) /* OUT : locked incore dquot */
	struct xfs_dquot	**O_dqpp)
{
	struct xfs_quotainfo	*qi = mp->m_quotainfo;
	struct radix_tree_root	*tree = xfs_dquot_tree(qi, type);
	struct xfs_dquot	*dqp;
	int			error;

	error = xfs_qm_dqget_checks(mp, type);
	if (error)
		return error;

restart:
	dqp = xfs_qm_dqget_cache_lookup(mp, qi, tree, id);
	if (dqp) {
		*O_dqpp = dqp;
		return 0;
	}

	error = xfs_qm_dqread(mp, id, type, flags, &dqp);
	if (error)
		return error;

	error = xfs_qm_dqget_cache_insert(mp, qi, tree, id, dqp);
	if (error) {
		/*
		 * Duplicate found. Just throw away the new dquot and start
		 * over.
		 */
		xfs_qm_dqdestroy(dqp);
		XFS_STATS_INC(mp, xs_qm_dquot_dups);
		goto restart;
	}

	trace_xfs_dqget_miss(dqp);
	*O_dqpp = dqp;
	return 0;
}

/* Return the quota id for a given inode and type. */
xfs_dqid_t
xfs_qm_id_for_quotatype(
	struct xfs_inode	*ip,
	uint			type)
{
{
	switch (type) {
	case XFS_DQ_USER:
		return ip->i_d.di_uid;
	case XFS_DQ_GROUP:
		return ip->i_d.di_gid;
	case XFS_DQ_PROJ:
		return xfs_get_projid(ip);
	}
	ASSERT(0);
	return 0;
}

/*
 * Return the dquot for a given inode and type.  If @can_alloc is true, then
 * allocate blocks if needed.  The inode's ILOCK must be held and it must not
 * have already had an inode attached.
 */
int
xfs_qm_dqget_inode(
	struct xfs_inode	*ip,
	uint			type,
	bool			can_alloc,
	struct xfs_dquot	**O_dqpp)
{
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_quotainfo	*qi = mp->m_quotainfo;
	struct xfs_quotainfo	*qi = mp->m_quotainfo;
	struct radix_tree_root	*tree = xfs_dquot_tree(qi, type);
	struct radix_tree_root	*tree = xfs_dquot_tree(qi, type);
	struct xfs_dquot	*dqp;
	struct xfs_dquot	*dqp;
	xfs_dqid_t		id;
	uint			flags = 0;
	int			error;
	int			error;


	error = xfs_qm_dqget_checks(mp, type);
	error = xfs_qm_dqget_checks(mp, type);
	if (error)
	if (error)
		return error;
		return error;


	if (ip) {
	if (can_alloc)
		flags |= XFS_QMOPT_DQALLOC;

	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
	ASSERT(xfs_inode_dquot(ip, type) == NULL);
	ASSERT(xfs_inode_dquot(ip, type) == NULL);
	}

	id = xfs_qm_id_for_quotatype(ip, type);


restart:
restart:
	dqp = xfs_qm_dqget_cache_lookup(mp, qi, tree, id);
	dqp = xfs_qm_dqget_cache_lookup(mp, qi, tree, id);
@@ -834,21 +901,15 @@ xfs_qm_dqget(
	 * lock here means dealing with a chown that can happen before
	 * lock here means dealing with a chown that can happen before
	 * we re-acquire the lock.
	 * we re-acquire the lock.
	 */
	 */
	if (ip)
	xfs_iunlock(ip, XFS_ILOCK_EXCL);
	xfs_iunlock(ip, XFS_ILOCK_EXCL);

	error = xfs_qm_dqread(mp, id, type, flags, &dqp);
	error = xfs_qm_dqread(mp, id, type, flags, &dqp);

	if (ip)
	xfs_ilock(ip, XFS_ILOCK_EXCL);
	xfs_ilock(ip, XFS_ILOCK_EXCL);

	if (error)
	if (error)
		return error;
		return error;


	if (ip) {
	/*
	/*
		 * A dquot could be attached to this inode by now, since
	 * A dquot could be attached to this inode by now, since we had
		 * we had dropped the ilock.
	 * dropped the ilock.
	 */
	 */
	if (xfs_this_quota_on(mp, type)) {
	if (xfs_this_quota_on(mp, type)) {
		struct xfs_dquot	*dqp1;
		struct xfs_dquot	*dqp1;
@@ -865,7 +926,6 @@ xfs_qm_dqget(
		xfs_qm_dqdestroy(dqp);
		xfs_qm_dqdestroy(dqp);
		return -ESRCH;
		return -ESRCH;
	}
	}
	}


	error = xfs_qm_dqget_cache_insert(mp, qi, tree, id, dqp);
	error = xfs_qm_dqget_cache_insert(mp, qi, tree, id, dqp);
	if (error) {
	if (error) {
@@ -879,7 +939,7 @@ xfs_qm_dqget(
	}
	}


dqret:
dqret:
	ASSERT((ip == NULL) || xfs_isilocked(ip, XFS_ILOCK_EXCL));
	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
	trace_xfs_dqget_miss(dqp);
	trace_xfs_dqget_miss(dqp);
	*O_dqpp = dqp;
	*O_dqpp = dqp;
	return 0;
	return 0;
@@ -901,7 +961,7 @@ xfs_qm_dqget_next(


	*dqpp = NULL;
	*dqpp = NULL;
	for (; !error; error = xfs_dq_get_next_id(mp, type, &id)) {
	for (; !error; error = xfs_dq_get_next_id(mp, type, &id)) {
		error = xfs_qm_dqget(mp, NULL, id, type, 0, &dqp);
		error = xfs_qm_dqget(mp, id, type, 0, &dqp);
		if (error == -ENOENT)
		if (error == -ENOENT)
			continue;
			continue;
		else if (error != 0)
		else if (error != 0)
+8 −2
Original line number Original line Diff line number Diff line
@@ -169,8 +169,14 @@ extern void xfs_qm_adjust_dqtimers(xfs_mount_t *,
					xfs_disk_dquot_t *);
					xfs_disk_dquot_t *);
extern void		xfs_qm_adjust_dqlimits(struct xfs_mount *,
extern void		xfs_qm_adjust_dqlimits(struct xfs_mount *,
					       struct xfs_dquot *);
					       struct xfs_dquot *);
extern int		xfs_qm_dqget(xfs_mount_t *, xfs_inode_t *,
extern xfs_dqid_t	xfs_qm_id_for_quotatype(struct xfs_inode *ip,
					xfs_dqid_t, uint, uint, xfs_dquot_t **);
					uint type);
extern int		xfs_qm_dqget(struct xfs_mount *mp, xfs_dqid_t id,
					uint type, uint flags,
					struct xfs_dquot **dqpp);
extern int		xfs_qm_dqget_inode(struct xfs_inode *ip, uint type,
					bool can_alloc,
					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 void		xfs_qm_dqput(xfs_dquot_t *);
extern void		xfs_qm_dqput(xfs_dquot_t *);
+1 −1
Original line number Original line Diff line number Diff line
@@ -576,7 +576,7 @@ xfs_file_iomap_begin_delay(
		goto done;
		goto done;
	}
	}


	error = xfs_qm_dqattach_locked(ip, 0);
	error = xfs_qm_dqattach_locked(ip, false);
	if (error)
	if (error)
		goto out_unlock;
		goto out_unlock;


+15 −24
Original line number Original line Diff line number Diff line
@@ -262,7 +262,7 @@ xfs_qm_dqattach_one(
	xfs_inode_t	*ip,
	xfs_inode_t	*ip,
	xfs_dqid_t	id,
	xfs_dqid_t	id,
	uint		type,
	uint		type,
	uint		doalloc,
	bool		doalloc,
	xfs_dquot_t	**IO_idqpp)
	xfs_dquot_t	**IO_idqpp)
{
{
	xfs_dquot_t	*dqp;
	xfs_dquot_t	*dqp;
@@ -288,7 +288,7 @@ xfs_qm_dqattach_one(
	 * exist on disk and we didn't ask it to allocate; ESRCH if quotas got
	 * exist on disk and we didn't ask it to allocate; ESRCH if quotas got
	 * turned off suddenly.
	 * turned off suddenly.
	 */
	 */
	error = xfs_qm_dqget(ip->i_mount, ip, id, type, doalloc, &dqp);
	error = xfs_qm_dqget_inode(ip, type, doalloc, &dqp);
	if (error)
	if (error)
		return error;
		return error;


@@ -330,7 +330,7 @@ xfs_qm_need_dqattach(
int
int
xfs_qm_dqattach_locked(
xfs_qm_dqattach_locked(
	xfs_inode_t	*ip,
	xfs_inode_t	*ip,
	uint		flags)
	bool		doalloc)
{
{
	xfs_mount_t	*mp = ip->i_mount;
	xfs_mount_t	*mp = ip->i_mount;
	int		error = 0;
	int		error = 0;
@@ -342,8 +342,7 @@ xfs_qm_dqattach_locked(


	if (XFS_IS_UQUOTA_ON(mp) && !ip->i_udquot) {
	if (XFS_IS_UQUOTA_ON(mp) && !ip->i_udquot) {
		error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER,
		error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER,
						flags & XFS_QMOPT_DQALLOC,
				doalloc, &ip->i_udquot);
						&ip->i_udquot);
		if (error)
		if (error)
			goto done;
			goto done;
		ASSERT(ip->i_udquot);
		ASSERT(ip->i_udquot);
@@ -351,8 +350,7 @@ xfs_qm_dqattach_locked(


	if (XFS_IS_GQUOTA_ON(mp) && !ip->i_gdquot) {
	if (XFS_IS_GQUOTA_ON(mp) && !ip->i_gdquot) {
		error = xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
		error = xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
						flags & XFS_QMOPT_DQALLOC,
				doalloc, &ip->i_gdquot);
						&ip->i_gdquot);
		if (error)
		if (error)
			goto done;
			goto done;
		ASSERT(ip->i_gdquot);
		ASSERT(ip->i_gdquot);
@@ -360,8 +358,7 @@ xfs_qm_dqattach_locked(


	if (XFS_IS_PQUOTA_ON(mp) && !ip->i_pdquot) {
	if (XFS_IS_PQUOTA_ON(mp) && !ip->i_pdquot) {
		error = xfs_qm_dqattach_one(ip, xfs_get_projid(ip), XFS_DQ_PROJ,
		error = xfs_qm_dqattach_one(ip, xfs_get_projid(ip), XFS_DQ_PROJ,
						flags & XFS_QMOPT_DQALLOC,
				doalloc, &ip->i_pdquot);
						&ip->i_pdquot);
		if (error)
		if (error)
			goto done;
			goto done;
		ASSERT(ip->i_pdquot);
		ASSERT(ip->i_pdquot);
@@ -386,7 +383,7 @@ xfs_qm_dqattach(
		return 0;
		return 0;


	xfs_ilock(ip, XFS_ILOCK_EXCL);
	xfs_ilock(ip, XFS_ILOCK_EXCL);
	error = xfs_qm_dqattach_locked(ip, 0);
	error = xfs_qm_dqattach_locked(ip, false);
	xfs_iunlock(ip, XFS_ILOCK_EXCL);
	xfs_iunlock(ip, XFS_ILOCK_EXCL);


	return error;
	return error;
@@ -1068,7 +1065,7 @@ xfs_qm_quotacheck_dqadjust(
	struct xfs_dquot	*dqp;
	struct xfs_dquot	*dqp;
	int			error;
	int			error;


	error = xfs_qm_dqget(mp, ip, id, type, XFS_QMOPT_DQALLOC, &dqp);
	error = xfs_qm_dqget_inode(ip, type, true, &dqp);
	if (error) {
	if (error) {
		/*
		/*
		 * Shouldn't be able to turn off quotas here.
		 * Shouldn't be able to turn off quotas here.
@@ -1667,7 +1664,7 @@ xfs_qm_vop_dqalloc(
	 * if necessary. The dquot(s) will not be locked.
	 * if necessary. The dquot(s) will not be locked.
	 */
	 */
	if (XFS_NOT_DQATTACHED(mp, ip)) {
	if (XFS_NOT_DQATTACHED(mp, ip)) {
		error = xfs_qm_dqattach_locked(ip, XFS_QMOPT_DQALLOC);
		error = xfs_qm_dqattach_locked(ip, true);
		if (error) {
		if (error) {
			xfs_iunlock(ip, lockflags);
			xfs_iunlock(ip, lockflags);
			return error;
			return error;
@@ -1686,10 +1683,8 @@ xfs_qm_vop_dqalloc(
			 * holding ilock.
			 * holding ilock.
			 */
			 */
			xfs_iunlock(ip, lockflags);
			xfs_iunlock(ip, lockflags);
			error = xfs_qm_dqget(mp, NULL, uid,
			error = xfs_qm_dqget(mp, uid, XFS_DQ_USER,
						 XFS_DQ_USER,
					XFS_QMOPT_DQALLOC, &uq);
						 XFS_QMOPT_DQALLOC,
						 &uq);
			if (error) {
			if (error) {
				ASSERT(error != -ENOENT);
				ASSERT(error != -ENOENT);
				return error;
				return error;
@@ -1712,10 +1707,8 @@ xfs_qm_vop_dqalloc(
	if ((flags & XFS_QMOPT_GQUOTA) && XFS_IS_GQUOTA_ON(mp)) {
	if ((flags & XFS_QMOPT_GQUOTA) && XFS_IS_GQUOTA_ON(mp)) {
		if (ip->i_d.di_gid != gid) {
		if (ip->i_d.di_gid != gid) {
			xfs_iunlock(ip, lockflags);
			xfs_iunlock(ip, lockflags);
			error = xfs_qm_dqget(mp, NULL, gid,
			error = xfs_qm_dqget(mp, gid, XFS_DQ_GROUP,
						 XFS_DQ_GROUP,
					XFS_QMOPT_DQALLOC, &gq);
						 XFS_QMOPT_DQALLOC,
						 &gq);
			if (error) {
			if (error) {
				ASSERT(error != -ENOENT);
				ASSERT(error != -ENOENT);
				goto error_rele;
				goto error_rele;
@@ -1731,10 +1724,8 @@ xfs_qm_vop_dqalloc(
	if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) {
	if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) {
		if (xfs_get_projid(ip) != prid) {
		if (xfs_get_projid(ip) != prid) {
			xfs_iunlock(ip, lockflags);
			xfs_iunlock(ip, lockflags);
			error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid,
			error = xfs_qm_dqget(mp, (xfs_dqid_t)prid, XFS_DQ_PROJ,
						 XFS_DQ_PROJ,
					XFS_QMOPT_DQALLOC, &pq);
						 XFS_QMOPT_DQALLOC,
						 &pq);
			if (error) {
			if (error) {
				ASSERT(error != -ENOENT);
				ASSERT(error != -ENOENT);
				goto error_rele;
				goto error_rele;
+1 −1
Original line number Original line Diff line number Diff line
@@ -72,7 +72,7 @@ xfs_qm_statvfs(
	xfs_mount_t		*mp = ip->i_mount;
	xfs_mount_t		*mp = ip->i_mount;
	xfs_dquot_t		*dqp;
	xfs_dquot_t		*dqp;


	if (!xfs_qm_dqget(mp, NULL, xfs_get_projid(ip), XFS_DQ_PROJ, 0, &dqp)) {
	if (!xfs_qm_dqget(mp, xfs_get_projid(ip), XFS_DQ_PROJ, 0, &dqp)) {
		xfs_fill_statvfs_from_dquot(statp, dqp);
		xfs_fill_statvfs_from_dquot(statp, dqp);
		xfs_qm_dqput(dqp);
		xfs_qm_dqput(dqp);
	}
	}
Loading