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

Commit a05931ce authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Ben Myers
Browse files

xfs: remove the global xfs_Gqm structure



If we initialize the slab caches for the quota code when XFS is loaded there
is no need for a global and reference counted quota manager structure.  Drop
all this overhead and also fix the error handling during quota initialization.

Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarBen Myers <bpm@sgi.com>
parent b84a3a96
Loading
Loading
Loading
Loading
+33 −2
Original line number Original line Diff line number Diff line
@@ -59,6 +59,9 @@ int xfs_dqreq_num;
int xfs_dqerror_mod = 33;
int xfs_dqerror_mod = 33;
#endif
#endif


struct kmem_zone		*xfs_qm_dqtrxzone;
static struct kmem_zone		*xfs_qm_dqzone;

static struct lock_class_key xfs_dquot_other_class;
static struct lock_class_key xfs_dquot_other_class;


/*
/*
@@ -71,7 +74,7 @@ xfs_qm_dqdestroy(
	ASSERT(list_empty(&dqp->q_lru));
	ASSERT(list_empty(&dqp->q_lru));


	mutex_destroy(&dqp->q_qlock);
	mutex_destroy(&dqp->q_qlock);
	kmem_zone_free(xfs_Gqm->qm_dqzone, dqp);
	kmem_zone_free(xfs_qm_dqzone, dqp);


	XFS_STATS_DEC(xs_qm_dquot);
	XFS_STATS_DEC(xs_qm_dquot);
}
}
@@ -491,7 +494,7 @@ xfs_qm_dqread(
	int			cancelflags = 0;
	int			cancelflags = 0;




	dqp = kmem_zone_zalloc(xfs_Gqm->qm_dqzone, KM_SLEEP);
	dqp = kmem_zone_zalloc(xfs_qm_dqzone, KM_SLEEP);


	dqp->dq_flags = type;
	dqp->dq_flags = type;
	dqp->q_core.d_id = cpu_to_be32(id);
	dqp->q_core.d_id = cpu_to_be32(id);
@@ -1040,3 +1043,31 @@ xfs_dqflock_pushbuf_wait(
out_lock:
out_lock:
	xfs_dqflock(dqp);
	xfs_dqflock(dqp);
}
}

int __init
xfs_qm_init(void)
{
	xfs_qm_dqzone =
		kmem_zone_init(sizeof(struct xfs_dquot), "xfs_dquot");
	if (!xfs_qm_dqzone)
		goto out;

	xfs_qm_dqtrxzone =
		kmem_zone_init(sizeof(struct xfs_dquot_acct), "xfs_dqtrx");
	if (!xfs_qm_dqtrxzone)
		goto out_free_dqzone;

	return 0;

out_free_dqzone:
	kmem_zone_destroy(xfs_qm_dqzone);
out:
	return -ENOMEM;
}

void __exit
xfs_qm_exit(void)
{
	kmem_zone_destroy(xfs_qm_dqtrxzone);
	kmem_zone_destroy(xfs_qm_dqzone);
}
+0 −132
Original line number Original line Diff line number Diff line
@@ -48,126 +48,10 @@
 * quota functionality, including maintaining the freelist and hash
 * quota functionality, including maintaining the freelist and hash
 * tables of dquots.
 * tables of dquots.
 */
 */
struct mutex	xfs_Gqm_lock;
struct xfs_qm	*xfs_Gqm;

kmem_zone_t	*qm_dqzone;
kmem_zone_t	*qm_dqtrxzone;

STATIC int	xfs_qm_init_quotainos(xfs_mount_t *);
STATIC int	xfs_qm_init_quotainos(xfs_mount_t *);
STATIC int	xfs_qm_init_quotainfo(xfs_mount_t *);
STATIC int	xfs_qm_init_quotainfo(xfs_mount_t *);
STATIC int	xfs_qm_shake(struct shrinker *, struct shrink_control *);
STATIC int	xfs_qm_shake(struct shrinker *, struct shrink_control *);


/*
 * Initialize the XQM structure.
 * Note that there is not one quota manager per file system.
 */
STATIC struct xfs_qm *
xfs_Gqm_init(void)
{
	xfs_qm_t	*xqm;

	xqm = kmem_zalloc(sizeof(xfs_qm_t), KM_SLEEP);

	/*
	 * dquot zone. we register our own low-memory callback.
	 */
	if (!qm_dqzone) {
		xqm->qm_dqzone = kmem_zone_init(sizeof(xfs_dquot_t),
						"xfs_dquots");
		qm_dqzone = xqm->qm_dqzone;
	} else
		xqm->qm_dqzone = qm_dqzone;

	/*
	 * The t_dqinfo portion of transactions.
	 */
	if (!qm_dqtrxzone) {
		xqm->qm_dqtrxzone = kmem_zone_init(sizeof(xfs_dquot_acct_t),
						   "xfs_dqtrx");
		qm_dqtrxzone = xqm->qm_dqtrxzone;
	} else
		xqm->qm_dqtrxzone = qm_dqtrxzone;

	xqm->qm_nrefs = 0;
	return xqm;
}

/*
 * Destroy the global quota manager when its reference count goes to zero.
 */
STATIC void
xfs_qm_destroy(
	struct xfs_qm	*xqm)
{
	ASSERT(xqm != NULL);
	ASSERT(xqm->qm_nrefs == 0);

	kmem_free(xqm);
}

/*
 * Called at mount time to let XQM know that another file system is
 * starting quotas. This isn't crucial information as the individual mount
 * structures are pretty independent, but it helps the XQM keep a
 * global view of what's going on.
 */
/* ARGSUSED */
STATIC int
xfs_qm_hold_quotafs_ref(
	struct xfs_mount *mp)
{
	/*
	 * Need to lock the xfs_Gqm structure for things like this. For example,
	 * the structure could disappear between the entry to this routine and
	 * a HOLD operation if not locked.
	 */
	mutex_lock(&xfs_Gqm_lock);

	if (!xfs_Gqm) {
		xfs_Gqm = xfs_Gqm_init();
		if (!xfs_Gqm) {
			mutex_unlock(&xfs_Gqm_lock);
			return ENOMEM;
		}
	}

	/*
	 * We can keep a list of all filesystems with quotas mounted for
	 * debugging and statistical purposes, but ...
	 * Just take a reference and get out.
	 */
	xfs_Gqm->qm_nrefs++;
	mutex_unlock(&xfs_Gqm_lock);

	return 0;
}


/*
 * Release the reference that a filesystem took at mount time,
 * so that we know when we need to destroy the entire quota manager.
 */
/* ARGSUSED */
STATIC void
xfs_qm_rele_quotafs_ref(
	struct xfs_mount *mp)
{
	ASSERT(xfs_Gqm);
	ASSERT(xfs_Gqm->qm_nrefs > 0);

	/*
	 * Destroy the entire XQM. If somebody mounts with quotaon, this'll
	 * be restarted.
	 */
	mutex_lock(&xfs_Gqm_lock);
	if (--xfs_Gqm->qm_nrefs == 0) {
		xfs_qm_destroy(xfs_Gqm);
		xfs_Gqm = NULL;
	}
	mutex_unlock(&xfs_Gqm_lock);
}

/*
/*
 * We use the batch lookup interface to iterate over the dquots as it
 * We use the batch lookup interface to iterate over the dquots as it
 * currently is the only interface into the radix tree code that allows
 * currently is the only interface into the radix tree code that allows
@@ -738,13 +622,6 @@ xfs_qm_init_quotainfo(


	ASSERT(XFS_IS_QUOTA_RUNNING(mp));
	ASSERT(XFS_IS_QUOTA_RUNNING(mp));


	/*
	 * Tell XQM that we exist as soon as possible.
	 */
	if ((error = xfs_qm_hold_quotafs_ref(mp))) {
		return error;
	}

	qinf = mp->m_quotainfo = kmem_zalloc(sizeof(xfs_quotainfo_t), KM_SLEEP);
	qinf = mp->m_quotainfo = kmem_zalloc(sizeof(xfs_quotainfo_t), KM_SLEEP);


	/*
	/*
@@ -850,17 +727,9 @@ xfs_qm_destroy_quotainfo(


	qi = mp->m_quotainfo;
	qi = mp->m_quotainfo;
	ASSERT(qi != NULL);
	ASSERT(qi != NULL);
	ASSERT(xfs_Gqm != NULL);


	unregister_shrinker(&qi->qi_shrinker);
	unregister_shrinker(&qi->qi_shrinker);


	/*
	 * Release the reference that XQM kept, so that we know
	 * when the XQM structure should be freed. We cannot assume
	 * that xfs_Gqm is non-null after this point.
	 */
	xfs_qm_rele_quotafs_ref(mp);

	if (qi->qi_uquotaip) {
	if (qi->qi_uquotaip) {
		IRELE(qi->qi_uquotaip);
		IRELE(qi->qi_uquotaip);
		qi->qi_uquotaip = NULL; /* paranoia */
		qi->qi_uquotaip = NULL; /* paranoia */
@@ -1447,7 +1316,6 @@ xfs_qm_quotacheck(
		 * We must turn off quotas.
		 * We must turn off quotas.
		 */
		 */
		ASSERT(mp->m_quotainfo != NULL);
		ASSERT(mp->m_quotainfo != NULL);
		ASSERT(xfs_Gqm != NULL);
		xfs_qm_destroy_quotainfo(mp);
		xfs_qm_destroy_quotainfo(mp);
		if (xfs_mount_reset_sbqflags(mp)) {
		if (xfs_mount_reset_sbqflags(mp)) {
			xfs_warn(mp,
			xfs_warn(mp,
+1 −14
Original line number Original line Diff line number Diff line
@@ -22,13 +22,9 @@
#include "xfs_dquot.h"
#include "xfs_dquot.h"
#include "xfs_quota_priv.h"
#include "xfs_quota_priv.h"


struct xfs_qm;
struct xfs_inode;
struct xfs_inode;


extern struct mutex	xfs_Gqm_lock;
extern struct kmem_zone	*xfs_qm_dqtrxzone;
extern struct xfs_qm	*xfs_Gqm;
extern kmem_zone_t	*qm_dqzone;
extern kmem_zone_t	*qm_dqtrxzone;


/*
/*
 * This defines the unit of allocation of dquots.
 * This defines the unit of allocation of dquots.
@@ -41,15 +37,6 @@ extern kmem_zone_t *qm_dqtrxzone;
 */
 */
#define XFS_DQUOT_CLUSTER_SIZE_FSB	(xfs_filblks_t)1
#define XFS_DQUOT_CLUSTER_SIZE_FSB	(xfs_filblks_t)1


/*
 * Quota Manager (global) structure. Lives only in core.
 */
typedef struct xfs_qm {
	uint		 qm_nrefs;	 /* file systems with quota on */
	kmem_zone_t	*qm_dqzone;	 /* dquot mem-alloc zone */
	kmem_zone_t	*qm_dqtrxzone;	 /* t_dqinfo of transactions */
} xfs_qm_t;

/*
/*
 * Various quota information for individual filesystems.
 * Various quota information for individual filesystems.
 * The mount structure keeps a pointer to this.
 * The mount structure keeps a pointer to this.
+0 −16
Original line number Original line Diff line number Diff line
@@ -156,19 +156,3 @@ xfs_qm_newmount(


	return 0;
	return 0;
}
}

void __init
xfs_qm_init(void)
{
	printk(KERN_INFO "SGI XFS Quota Management subsystem\n");
	mutex_init(&xfs_Gqm_lock);
}

void __exit
xfs_qm_exit(void)
{
	if (qm_dqzone)
		kmem_zone_destroy(qm_dqzone);
	if (qm_dqtrxzone)
		kmem_zone_destroy(qm_dqtrxzone);
}
+7 −3
Original line number Original line Diff line number Diff line
@@ -1654,13 +1654,17 @@ init_xfs_fs(void)
	if (error)
	if (error)
		goto out_cleanup_procfs;
		goto out_cleanup_procfs;


	vfs_initquota();
	error = xfs_qm_init();
	if (error)
		goto out_sysctl_unregister;


	error = register_filesystem(&xfs_fs_type);
	error = register_filesystem(&xfs_fs_type);
	if (error)
	if (error)
		goto out_sysctl_unregister;
		goto out_qm_exit;
	return 0;
	return 0;


 out_qm_exit:
	xfs_qm_exit();
 out_sysctl_unregister:
 out_sysctl_unregister:
	xfs_sysctl_unregister();
	xfs_sysctl_unregister();
 out_cleanup_procfs:
 out_cleanup_procfs:
@@ -1682,7 +1686,7 @@ init_xfs_fs(void)
STATIC void __exit
STATIC void __exit
exit_xfs_fs(void)
exit_xfs_fs(void)
{
{
	vfs_exitquota();
	xfs_qm_exit();
	unregister_filesystem(&xfs_fs_type);
	unregister_filesystem(&xfs_fs_type);
	xfs_sysctl_unregister();
	xfs_sysctl_unregister();
	xfs_cleanup_procfs();
	xfs_cleanup_procfs();
Loading