* Lock order:
*
* ip->i_lock
- * qi->qi_tree_lock
+ * qi->qi_xa_lock
* dquot->q_qlock (xfs_dqlock() and friends)
* dquot->q_flush (xfs_dqflock() and friends)
* qi->qi_lru_lock
xfs_qm_dqget_cache_lookup(
struct xfs_mount *mp,
struct xfs_quotainfo *qi,
- struct radix_tree_root *tree,
+ struct xarray *xa,
xfs_dqid_t id)
{
struct xfs_dquot *dqp;
restart:
- mutex_lock(&qi->qi_tree_lock);
- dqp = radix_tree_lookup(tree, id);
+ mutex_lock(&qi->qi_xa_lock);
+ dqp = xa_load(xa, id);
if (!dqp) {
- mutex_unlock(&qi->qi_tree_lock);
+ mutex_unlock(&qi->qi_xa_lock);
XFS_STATS_INC(mp, xs_qm_dqcachemisses);
return NULL;
}
xfs_dqlock(dqp);
if (dqp->dq_flags & XFS_DQ_FREEING) {
xfs_dqunlock(dqp);
- mutex_unlock(&qi->qi_tree_lock);
+ mutex_unlock(&qi->qi_xa_lock);
trace_xfs_dqget_freeing(dqp);
delay(1);
goto restart;
}
dqp->q_nrefs++;
- mutex_unlock(&qi->qi_tree_lock);
+ mutex_unlock(&qi->qi_xa_lock);
trace_xfs_dqget_hit(dqp);
XFS_STATS_INC(mp, xs_qm_dqcachehits);
xfs_qm_dqget_cache_insert(
struct xfs_mount *mp,
struct xfs_quotainfo *qi,
- struct radix_tree_root *tree,
+ struct xarray *xa,
xfs_dqid_t id,
struct xfs_dquot *dqp)
{
int error;
- mutex_lock(&qi->qi_tree_lock);
- error = radix_tree_insert(tree, id, dqp);
+ mutex_lock(&qi->qi_xa_lock);
+ error = xa_insert(xa, id, dqp, GFP_NOFS);
if (unlikely(error)) {
/* Duplicate found! Caller must try again. */
- WARN_ON(error != -EEXIST);
- mutex_unlock(&qi->qi_tree_lock);
+ WARN_ON(error != -EBUSY);
+ mutex_unlock(&qi->qi_xa_lock);
trace_xfs_dqget_dup(dqp);
return error;
}
dqp->q_nrefs = 1;
qi->qi_dquots++;
- mutex_unlock(&qi->qi_tree_lock);
+ mutex_unlock(&qi->qi_xa_lock);
return 0;
}
struct xfs_dquot **O_dqpp)
{
struct xfs_quotainfo *qi = mp->m_quotainfo;
- struct radix_tree_root *tree = xfs_dquot_tree(qi, type);
+ struct xarray *xa = xfs_dquot_xa(qi, type);
struct xfs_dquot *dqp;
int error;
return error;
restart:
- dqp = xfs_qm_dqget_cache_lookup(mp, qi, tree, id);
+ dqp = xfs_qm_dqget_cache_lookup(mp, qi, xa, id);
if (dqp) {
*O_dqpp = dqp;
return 0;
if (error)
return error;
- error = xfs_qm_dqget_cache_insert(mp, qi, tree, id, dqp);
+ error = xfs_qm_dqget_cache_insert(mp, qi, xa, id, dqp);
if (error) {
/*
* Duplicate found. Just throw away the new dquot and start
{
struct xfs_mount *mp = ip->i_mount;
struct xfs_quotainfo *qi = mp->m_quotainfo;
- struct radix_tree_root *tree = xfs_dquot_tree(qi, type);
+ struct xarray *xa = xfs_dquot_xa(qi, type);
struct xfs_dquot *dqp;
xfs_dqid_t id;
int error;
id = xfs_qm_id_for_quotatype(ip, type);
restart:
- dqp = xfs_qm_dqget_cache_lookup(mp, qi, tree, id);
+ dqp = xfs_qm_dqget_cache_lookup(mp, qi, xa, id);
if (dqp) {
*O_dqpp = dqp;
return 0;
return -ESRCH;
}
- error = xfs_qm_dqget_cache_insert(mp, qi, tree, id, dqp);
+ error = xfs_qm_dqget_cache_insert(mp, qi, xa, id, dqp);
if (error) {
/*
* Duplicate found. Just throw away the new dquot and start
void *data)
{
struct xfs_quotainfo *qi = mp->m_quotainfo;
- struct radix_tree_root *tree = xfs_dquot_tree(qi, type);
+ struct xarray *xa = xfs_dquot_xa(qi, type);
uint32_t next_index;
int last_error = 0;
int skipped;
int error = 0;
int i;
- mutex_lock(&qi->qi_tree_lock);
- nr_found = radix_tree_gang_lookup(tree, (void **)batch,
- next_index, XFS_DQ_LOOKUP_BATCH);
+ mutex_lock(&qi->qi_xa_lock);
+ nr_found = xa_extract(xa, (void **)batch, next_index,
+ ULONG_MAX, XFS_DQ_LOOKUP_BATCH, XA_PRESENT);
if (!nr_found) {
- mutex_unlock(&qi->qi_tree_lock);
+ mutex_unlock(&qi->qi_xa_lock);
break;
}
last_error = error;
}
- mutex_unlock(&qi->qi_tree_lock);
+ mutex_unlock(&qi->qi_xa_lock);
/* bail out if the filesystem is corrupted. */
if (last_error == -EFSCORRUPTED) {
xfs_dqfunlock(dqp);
xfs_dqunlock(dqp);
- radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags),
+ xa_erase(xfs_dquot_xa(qi, dqp->q_core.d_flags),
be32_to_cpu(dqp->q_core.d_id));
qi->qi_dquots--;
if (error)
goto out_free_lru;
- INIT_RADIX_TREE(&qinf->qi_uquota_tree, GFP_NOFS);
- INIT_RADIX_TREE(&qinf->qi_gquota_tree, GFP_NOFS);
- INIT_RADIX_TREE(&qinf->qi_pquota_tree, GFP_NOFS);
- mutex_init(&qinf->qi_tree_lock);
+ xa_init(&qinf->qi_uquota_xa);
+ xa_init(&qinf->qi_gquota_xa);
+ xa_init(&qinf->qi_pquota_xa);
+ mutex_init(&qinf->qi_xa_lock);
/* mutex used to serialize quotaoffs */
mutex_init(&qinf->qi_quotaofflock);
out_free_inos:
mutex_destroy(&qinf->qi_quotaofflock);
- mutex_destroy(&qinf->qi_tree_lock);
+ mutex_destroy(&qinf->qi_xa_lock);
xfs_qm_destroy_quotainos(qinf);
out_free_lru:
list_lru_destroy(&qinf->qi_lru);
unregister_shrinker(&qi->qi_shrinker);
list_lru_destroy(&qi->qi_lru);
xfs_qm_destroy_quotainos(qi);
- mutex_destroy(&qi->qi_tree_lock);
+ mutex_destroy(&qi->qi_xa_lock);
mutex_destroy(&qi->qi_quotaofflock);
kmem_free(qi);
mp->m_quotainfo = NULL;
struct xfs_mount *mp = dqp->q_mount;
struct xfs_quotainfo *qi = mp->m_quotainfo;
- mutex_lock(&qi->qi_tree_lock);
- radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags),
+ mutex_lock(&qi->qi_xa_lock);
+ xa_erase(xfs_dquot_xa(qi, dqp->q_core.d_flags),
be32_to_cpu(dqp->q_core.d_id));
qi->qi_dquots--;
- mutex_unlock(&qi->qi_tree_lock);
+ mutex_unlock(&qi->qi_xa_lock);
xfs_qm_dqdestroy(dqp);
}
* The mount structure keeps a pointer to this.
*/
typedef struct xfs_quotainfo {
- struct radix_tree_root qi_uquota_tree;
- struct radix_tree_root qi_gquota_tree;
- struct radix_tree_root qi_pquota_tree;
- struct mutex qi_tree_lock;
+ struct xarray qi_uquota_xa;
+ struct xarray qi_gquota_xa;
+ struct xarray qi_pquota_xa;
+ struct mutex qi_xa_lock;
struct xfs_inode *qi_uquotaip; /* user quota inode */
struct xfs_inode *qi_gquotaip; /* group quota inode */
struct xfs_inode *qi_pquotaip; /* project quota inode */
struct shrinker qi_shrinker;
} xfs_quotainfo_t;
-static inline struct radix_tree_root *
-xfs_dquot_tree(
+static inline struct xarray *
+xfs_dquot_xa(
struct xfs_quotainfo *qi,
int type)
{
switch (type) {
case XFS_DQ_USER:
- return &qi->qi_uquota_tree;
+ return &qi->qi_uquota_xa;
case XFS_DQ_GROUP:
- return &qi->qi_gquota_tree;
+ return &qi->qi_gquota_xa;
case XFS_DQ_PROJ:
- return &qi->qi_pquota_tree;
+ return &qi->qi_pquota_xa;
default:
ASSERT(0);
}