quota: optimize i_dquot access

Remove redundant calls of i_dquot(), keep pointer in local variable.

add/remove: 0/0 grow/shrink: 3/7 up/down: 40/-278 (-238)
function                                     old     new   delta
__dquot_free_space                           734     750     +16
__dquot_alloc_space                          484     500     +16
dquot_free_inode                             324     332      +8
dquot_drop                                    82      69     -13
vfs_load_quota_inode                        1357    1341     -16
dquot_reclaim_space_nodirty                  348     316     -32
dquot_disable                               1980    1944     -36
dquot_claim_space_nodirty                    354     314     -40
__dquot_drop                                 125      83     -42
__dquot_initialize                           522     423     -99

Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
Signed-off-by: Jan Kara <jack@suse.cz>
This commit is contained in:
Konstantin Khlebnikov 2015-02-12 12:36:37 +03:00 committed by Jan Kara
parent 023a6007a0
commit 5bcd3b6f63
1 changed files with 39 additions and 24 deletions

View File

@ -900,14 +900,17 @@ static inline struct dquot **i_dquot(struct inode *inode)
static int dqinit_needed(struct inode *inode, int type) static int dqinit_needed(struct inode *inode, int type)
{ {
struct dquot * const *dquots;
int cnt; int cnt;
if (IS_NOQUOTA(inode)) if (IS_NOQUOTA(inode))
return 0; return 0;
dquots = i_dquot(inode);
if (type != -1) if (type != -1)
return !i_dquot(inode)[type]; return !dquots[type];
for (cnt = 0; cnt < MAXQUOTAS; cnt++) for (cnt = 0; cnt < MAXQUOTAS; cnt++)
if (!i_dquot(inode)[cnt]) if (!dquots[cnt])
return 1; return 1;
return 0; return 0;
} }
@ -970,12 +973,13 @@ static void add_dquot_ref(struct super_block *sb, int type)
static void remove_inode_dquot_ref(struct inode *inode, int type, static void remove_inode_dquot_ref(struct inode *inode, int type,
struct list_head *tofree_head) struct list_head *tofree_head)
{ {
struct dquot *dquot = i_dquot(inode)[type]; struct dquot **dquots = i_dquot(inode);
struct dquot *dquot = dquots[type];
i_dquot(inode)[type] = NULL;
if (!dquot) if (!dquot)
return; return;
dquots[type] = NULL;
if (list_empty(&dquot->dq_free)) { if (list_empty(&dquot->dq_free)) {
/* /*
* The inode still has reference to dquot so it can't be in the * The inode still has reference to dquot so it can't be in the
@ -1389,13 +1393,15 @@ static int dquot_active(const struct inode *inode)
static void __dquot_initialize(struct inode *inode, int type) static void __dquot_initialize(struct inode *inode, int type)
{ {
int cnt, init_needed = 0; int cnt, init_needed = 0;
struct dquot *got[MAXQUOTAS]; struct dquot **dquots, *got[MAXQUOTAS];
struct super_block *sb = inode->i_sb; struct super_block *sb = inode->i_sb;
qsize_t rsv; qsize_t rsv;
if (!dquot_active(inode)) if (!dquot_active(inode))
return; return;
dquots = i_dquot(inode);
/* First get references to structures we might need. */ /* First get references to structures we might need. */
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
struct kqid qid; struct kqid qid;
@ -1407,7 +1413,7 @@ static void __dquot_initialize(struct inode *inode, int type)
* we check it without locking here to avoid unnecessary * we check it without locking here to avoid unnecessary
* dqget()/dqput() calls. * dqget()/dqput() calls.
*/ */
if (i_dquot(inode)[cnt]) if (dquots[cnt])
continue; continue;
init_needed = 1; init_needed = 1;
@ -1438,8 +1444,8 @@ static void __dquot_initialize(struct inode *inode, int type)
/* We could race with quotaon or dqget() could have failed */ /* We could race with quotaon or dqget() could have failed */
if (!got[cnt]) if (!got[cnt])
continue; continue;
if (!i_dquot(inode)[cnt]) { if (!dquots[cnt]) {
i_dquot(inode)[cnt] = got[cnt]; dquots[cnt] = got[cnt];
got[cnt] = NULL; got[cnt] = NULL;
/* /*
* Make quota reservation system happy if someone * Make quota reservation system happy if someone
@ -1447,7 +1453,7 @@ static void __dquot_initialize(struct inode *inode, int type)
*/ */
rsv = inode_get_rsv_space(inode); rsv = inode_get_rsv_space(inode);
if (unlikely(rsv)) if (unlikely(rsv))
dquot_resv_space(i_dquot(inode)[cnt], rsv); dquot_resv_space(dquots[cnt], rsv);
} }
} }
out_err: out_err:
@ -1473,12 +1479,13 @@ EXPORT_SYMBOL(dquot_initialize);
static void __dquot_drop(struct inode *inode) static void __dquot_drop(struct inode *inode)
{ {
int cnt; int cnt;
struct dquot **dquots = i_dquot(inode);
struct dquot *put[MAXQUOTAS]; struct dquot *put[MAXQUOTAS];
spin_lock(&dq_data_lock); spin_lock(&dq_data_lock);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
put[cnt] = i_dquot(inode)[cnt]; put[cnt] = dquots[cnt];
i_dquot(inode)[cnt] = NULL; dquots[cnt] = NULL;
} }
spin_unlock(&dq_data_lock); spin_unlock(&dq_data_lock);
dqput_all(put); dqput_all(put);
@ -1486,6 +1493,7 @@ static void __dquot_drop(struct inode *inode)
void dquot_drop(struct inode *inode) void dquot_drop(struct inode *inode)
{ {
struct dquot * const *dquots;
int cnt; int cnt;
if (IS_NOQUOTA(inode)) if (IS_NOQUOTA(inode))
@ -1498,8 +1506,9 @@ void dquot_drop(struct inode *inode)
* must assure that nobody can come after the DQUOT_DROP and * must assure that nobody can come after the DQUOT_DROP and
* add quota pointers back anyway. * add quota pointers back anyway.
*/ */
dquots = i_dquot(inode);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (i_dquot(inode)[cnt]) if (dquots[cnt])
break; break;
} }
@ -1600,8 +1609,8 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
{ {
int cnt, ret = 0, index; int cnt, ret = 0, index;
struct dquot_warn warn[MAXQUOTAS]; struct dquot_warn warn[MAXQUOTAS];
struct dquot **dquots = i_dquot(inode);
int reserve = flags & DQUOT_SPACE_RESERVE; int reserve = flags & DQUOT_SPACE_RESERVE;
struct dquot **dquots;
if (!dquot_active(inode)) { if (!dquot_active(inode)) {
inode_incr_space(inode, number, reserve); inode_incr_space(inode, number, reserve);
@ -1611,6 +1620,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
for (cnt = 0; cnt < MAXQUOTAS; cnt++) for (cnt = 0; cnt < MAXQUOTAS; cnt++)
warn[cnt].w_type = QUOTA_NL_NOWARN; warn[cnt].w_type = QUOTA_NL_NOWARN;
dquots = i_dquot(inode);
index = srcu_read_lock(&dquot_srcu); index = srcu_read_lock(&dquot_srcu);
spin_lock(&dq_data_lock); spin_lock(&dq_data_lock);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
@ -1652,13 +1662,14 @@ int dquot_alloc_inode(struct inode *inode)
{ {
int cnt, ret = 0, index; int cnt, ret = 0, index;
struct dquot_warn warn[MAXQUOTAS]; struct dquot_warn warn[MAXQUOTAS];
struct dquot * const *dquots = i_dquot(inode); struct dquot * const *dquots;
if (!dquot_active(inode)) if (!dquot_active(inode))
return 0; return 0;
for (cnt = 0; cnt < MAXQUOTAS; cnt++) for (cnt = 0; cnt < MAXQUOTAS; cnt++)
warn[cnt].w_type = QUOTA_NL_NOWARN; warn[cnt].w_type = QUOTA_NL_NOWARN;
dquots = i_dquot(inode);
index = srcu_read_lock(&dquot_srcu); index = srcu_read_lock(&dquot_srcu);
spin_lock(&dq_data_lock); spin_lock(&dq_data_lock);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
@ -1690,6 +1701,7 @@ EXPORT_SYMBOL(dquot_alloc_inode);
*/ */
int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
{ {
struct dquot **dquots;
int cnt, index; int cnt, index;
if (!dquot_active(inode)) { if (!dquot_active(inode)) {
@ -1697,18 +1709,18 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
return 0; return 0;
} }
dquots = i_dquot(inode);
index = srcu_read_lock(&dquot_srcu); index = srcu_read_lock(&dquot_srcu);
spin_lock(&dq_data_lock); spin_lock(&dq_data_lock);
/* Claim reserved quotas to allocated quotas */ /* Claim reserved quotas to allocated quotas */
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (i_dquot(inode)[cnt]) if (dquots[cnt])
dquot_claim_reserved_space(i_dquot(inode)[cnt], dquot_claim_reserved_space(dquots[cnt], number);
number);
} }
/* Update inode bytes */ /* Update inode bytes */
inode_claim_rsv_space(inode, number); inode_claim_rsv_space(inode, number);
spin_unlock(&dq_data_lock); spin_unlock(&dq_data_lock);
mark_all_dquot_dirty(i_dquot(inode)); mark_all_dquot_dirty(dquots);
srcu_read_unlock(&dquot_srcu, index); srcu_read_unlock(&dquot_srcu, index);
return 0; return 0;
} }
@ -1719,6 +1731,7 @@ EXPORT_SYMBOL(dquot_claim_space_nodirty);
*/ */
void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number)
{ {
struct dquot **dquots;
int cnt, index; int cnt, index;
if (!dquot_active(inode)) { if (!dquot_active(inode)) {
@ -1726,18 +1739,18 @@ void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number)
return; return;
} }
dquots = i_dquot(inode);
index = srcu_read_lock(&dquot_srcu); index = srcu_read_lock(&dquot_srcu);
spin_lock(&dq_data_lock); spin_lock(&dq_data_lock);
/* Claim reserved quotas to allocated quotas */ /* Claim reserved quotas to allocated quotas */
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (i_dquot(inode)[cnt]) if (dquots[cnt])
dquot_reclaim_reserved_space(i_dquot(inode)[cnt], dquot_reclaim_reserved_space(dquots[cnt], number);
number);
} }
/* Update inode bytes */ /* Update inode bytes */
inode_reclaim_rsv_space(inode, number); inode_reclaim_rsv_space(inode, number);
spin_unlock(&dq_data_lock); spin_unlock(&dq_data_lock);
mark_all_dquot_dirty(i_dquot(inode)); mark_all_dquot_dirty(dquots);
srcu_read_unlock(&dquot_srcu, index); srcu_read_unlock(&dquot_srcu, index);
return; return;
} }
@ -1750,7 +1763,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
{ {
unsigned int cnt; unsigned int cnt;
struct dquot_warn warn[MAXQUOTAS]; struct dquot_warn warn[MAXQUOTAS];
struct dquot **dquots = i_dquot(inode); struct dquot **dquots;
int reserve = flags & DQUOT_SPACE_RESERVE, index; int reserve = flags & DQUOT_SPACE_RESERVE, index;
if (!dquot_active(inode)) { if (!dquot_active(inode)) {
@ -1758,6 +1771,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
return; return;
} }
dquots = i_dquot(inode);
index = srcu_read_lock(&dquot_srcu); index = srcu_read_lock(&dquot_srcu);
spin_lock(&dq_data_lock); spin_lock(&dq_data_lock);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
@ -1793,12 +1807,13 @@ void dquot_free_inode(struct inode *inode)
{ {
unsigned int cnt; unsigned int cnt;
struct dquot_warn warn[MAXQUOTAS]; struct dquot_warn warn[MAXQUOTAS];
struct dquot * const *dquots = i_dquot(inode); struct dquot * const *dquots;
int index; int index;
if (!dquot_active(inode)) if (!dquot_active(inode))
return; return;
dquots = i_dquot(inode);
index = srcu_read_lock(&dquot_srcu); index = srcu_read_lock(&dquot_srcu);
spin_lock(&dq_data_lock); spin_lock(&dq_data_lock);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {