diff options
| author | Niu Yawei <yawei.niu@gmail.com> | 2014-06-04 00:20:30 -0400 |
|---|---|---|
| committer | Jan Kara <jack@suse.cz> | 2014-07-15 16:40:21 -0400 |
| commit | 1ea06bec78a128adc995ca32bd906a6c9bb9cf91 (patch) | |
| tree | e306601eeb564fcc425841f8591df5069e3a9d15 | |
| parent | 606cdcca04a609ed4dfbfe788942de9477da556b (diff) | |
quota: avoid unnecessary dqget()/dqput() calls
Avoid unnecessary dqget()/dqput() calls in __dquot_initialize(),
that will introduce global lock contention otherwise.
Signed-off-by: Lai Siyao <lai.siyao@intel.com>
Signed-off-by: Niu Yawei <yawei.niu@intel.com>
Signed-off-by: Jan Kara <jack@suse.cz>
| -rw-r--r-- | fs/quota/dquot.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 7f30bdc57d13..251771916069 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
| @@ -1402,7 +1402,7 @@ static int dquot_active(const struct inode *inode) | |||
| 1402 | */ | 1402 | */ |
| 1403 | static void __dquot_initialize(struct inode *inode, int type) | 1403 | static void __dquot_initialize(struct inode *inode, int type) |
| 1404 | { | 1404 | { |
| 1405 | int cnt; | 1405 | int cnt, init_needed = 0; |
| 1406 | struct dquot *got[MAXQUOTAS]; | 1406 | struct dquot *got[MAXQUOTAS]; |
| 1407 | struct super_block *sb = inode->i_sb; | 1407 | struct super_block *sb = inode->i_sb; |
| 1408 | qsize_t rsv; | 1408 | qsize_t rsv; |
| @@ -1418,6 +1418,15 @@ static void __dquot_initialize(struct inode *inode, int type) | |||
| 1418 | got[cnt] = NULL; | 1418 | got[cnt] = NULL; |
| 1419 | if (type != -1 && cnt != type) | 1419 | if (type != -1 && cnt != type) |
| 1420 | continue; | 1420 | continue; |
| 1421 | /* | ||
| 1422 | * The i_dquot should have been initialized in most cases, | ||
| 1423 | * we check it without locking here to avoid unnecessary | ||
| 1424 | * dqget()/dqput() calls. | ||
| 1425 | */ | ||
| 1426 | if (inode->i_dquot[cnt]) | ||
| 1427 | continue; | ||
| 1428 | init_needed = 1; | ||
| 1429 | |||
| 1421 | switch (cnt) { | 1430 | switch (cnt) { |
| 1422 | case USRQUOTA: | 1431 | case USRQUOTA: |
| 1423 | qid = make_kqid_uid(inode->i_uid); | 1432 | qid = make_kqid_uid(inode->i_uid); |
| @@ -1429,6 +1438,10 @@ static void __dquot_initialize(struct inode *inode, int type) | |||
| 1429 | got[cnt] = dqget(sb, qid); | 1438 | got[cnt] = dqget(sb, qid); |
| 1430 | } | 1439 | } |
| 1431 | 1440 | ||
| 1441 | /* All required i_dquot has been initialized */ | ||
| 1442 | if (!init_needed) | ||
| 1443 | return; | ||
| 1444 | |||
| 1432 | down_write(&sb_dqopt(sb)->dqptr_sem); | 1445 | down_write(&sb_dqopt(sb)->dqptr_sem); |
| 1433 | if (IS_NOQUOTA(inode)) | 1446 | if (IS_NOQUOTA(inode)) |
| 1434 | goto out_err; | 1447 | goto out_err; |
