Commit ae4f6ef1 authored by Jan Kara's avatar Jan Kara

ocfs2: Avoid unnecessary block mapping when refreshing quota info

The position of global quota file info does not change. So we do not have
to do logical -> physical block translation every time we reread it from
disk. Thus we can also avoid taking ip_alloc_sem.
Acked-by: default avatarJoel Becker <Joel.Becker@oracle.com>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent f64dd44e
...@@ -3897,7 +3897,8 @@ static int ocfs2_refresh_qinfo(struct ocfs2_mem_dqinfo *oinfo) ...@@ -3897,7 +3897,8 @@ static int ocfs2_refresh_qinfo(struct ocfs2_mem_dqinfo *oinfo)
oinfo->dqi_gi.dqi_free_entry = oinfo->dqi_gi.dqi_free_entry =
be32_to_cpu(lvb->lvb_free_entry); be32_to_cpu(lvb->lvb_free_entry);
} else { } else {
status = ocfs2_read_quota_block(oinfo->dqi_gqinode, 0, &bh); status = ocfs2_read_quota_phys_block(oinfo->dqi_gqinode,
oinfo->dqi_giblk, &bh);
if (status) { if (status) {
mlog_errno(status); mlog_errno(status);
goto bail; goto bail;
......
...@@ -52,8 +52,9 @@ struct ocfs2_mem_dqinfo { ...@@ -52,8 +52,9 @@ struct ocfs2_mem_dqinfo {
struct ocfs2_lock_res dqi_gqlock; /* Lock protecting quota information structure */ struct ocfs2_lock_res dqi_gqlock; /* Lock protecting quota information structure */
struct buffer_head *dqi_gqi_bh; /* Buffer head with global quota file inode - set only if inode lock is obtained */ struct buffer_head *dqi_gqi_bh; /* Buffer head with global quota file inode - set only if inode lock is obtained */
int dqi_gqi_count; /* Number of holders of dqi_gqi_bh */ int dqi_gqi_count; /* Number of holders of dqi_gqi_bh */
u64 dqi_giblk; /* Number of block with global information header */
struct buffer_head *dqi_lqi_bh; /* Buffer head with local quota file inode */ struct buffer_head *dqi_lqi_bh; /* Buffer head with local quota file inode */
struct buffer_head *dqi_ibh; /* Buffer with information header */ struct buffer_head *dqi_libh; /* Buffer with local information header */
struct qtree_mem_dqinfo dqi_gi; /* Info about global file */ struct qtree_mem_dqinfo dqi_gi; /* Info about global file */
struct delayed_work dqi_sync_work; /* Work for syncing dquots */ struct delayed_work dqi_sync_work; /* Work for syncing dquots */
struct ocfs2_quota_recovery *dqi_rec; /* Pointer to recovery struct ocfs2_quota_recovery *dqi_rec; /* Pointer to recovery
......
...@@ -325,6 +325,7 @@ int ocfs2_global_read_info(struct super_block *sb, int type) ...@@ -325,6 +325,7 @@ int ocfs2_global_read_info(struct super_block *sb, int type)
struct ocfs2_global_disk_dqinfo dinfo; struct ocfs2_global_disk_dqinfo dinfo;
struct mem_dqinfo *info = sb_dqinfo(sb, type); struct mem_dqinfo *info = sb_dqinfo(sb, type);
struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv; struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
u64 pcount;
int status; int status;
mlog_entry_void(); mlog_entry_void();
...@@ -351,9 +352,19 @@ int ocfs2_global_read_info(struct super_block *sb, int type) ...@@ -351,9 +352,19 @@ int ocfs2_global_read_info(struct super_block *sb, int type)
mlog_errno(status); mlog_errno(status);
goto out_err; goto out_err;
} }
status = ocfs2_extent_map_get_blocks(gqinode, 0, &oinfo->dqi_giblk,
&pcount, NULL);
if (status < 0)
goto out_unlock;
status = ocfs2_qinfo_lock(oinfo, 0);
if (status < 0)
goto out_unlock;
status = sb->s_op->quota_read(sb, type, (char *)&dinfo, status = sb->s_op->quota_read(sb, type, (char *)&dinfo,
sizeof(struct ocfs2_global_disk_dqinfo), sizeof(struct ocfs2_global_disk_dqinfo),
OCFS2_GLOBAL_INFO_OFF); OCFS2_GLOBAL_INFO_OFF);
ocfs2_qinfo_unlock(oinfo, 0);
ocfs2_unlock_global_qf(oinfo, 0); ocfs2_unlock_global_qf(oinfo, 0);
if (status != sizeof(struct ocfs2_global_disk_dqinfo)) { if (status != sizeof(struct ocfs2_global_disk_dqinfo)) {
mlog(ML_ERROR, "Cannot read global quota info (%d).\n", mlog(ML_ERROR, "Cannot read global quota info (%d).\n",
...@@ -380,6 +391,10 @@ int ocfs2_global_read_info(struct super_block *sb, int type) ...@@ -380,6 +391,10 @@ int ocfs2_global_read_info(struct super_block *sb, int type)
out_err: out_err:
mlog_exit(status); mlog_exit(status);
return status; return status;
out_unlock:
ocfs2_unlock_global_qf(oinfo, 0);
mlog_errno(status);
goto out_err;
} }
/* Write information to global quota file. Expects exlusive lock on quota /* Write information to global quota file. Expects exlusive lock on quota
......
...@@ -671,7 +671,7 @@ static int ocfs2_local_read_info(struct super_block *sb, int type) ...@@ -671,7 +671,7 @@ static int ocfs2_local_read_info(struct super_block *sb, int type)
INIT_LIST_HEAD(&oinfo->dqi_chunk); INIT_LIST_HEAD(&oinfo->dqi_chunk);
oinfo->dqi_rec = NULL; oinfo->dqi_rec = NULL;
oinfo->dqi_lqi_bh = NULL; oinfo->dqi_lqi_bh = NULL;
oinfo->dqi_ibh = NULL; oinfo->dqi_libh = NULL;
status = ocfs2_global_read_info(sb, type); status = ocfs2_global_read_info(sb, type);
if (status < 0) if (status < 0)
...@@ -697,7 +697,7 @@ static int ocfs2_local_read_info(struct super_block *sb, int type) ...@@ -697,7 +697,7 @@ static int ocfs2_local_read_info(struct super_block *sb, int type)
info->dqi_flags = le32_to_cpu(ldinfo->dqi_flags); info->dqi_flags = le32_to_cpu(ldinfo->dqi_flags);
oinfo->dqi_chunks = le32_to_cpu(ldinfo->dqi_chunks); oinfo->dqi_chunks = le32_to_cpu(ldinfo->dqi_chunks);
oinfo->dqi_blocks = le32_to_cpu(ldinfo->dqi_blocks); oinfo->dqi_blocks = le32_to_cpu(ldinfo->dqi_blocks);
oinfo->dqi_ibh = bh; oinfo->dqi_libh = bh;
/* We crashed when using local quota file? */ /* We crashed when using local quota file? */
if (!(info->dqi_flags & OLQF_CLEAN)) { if (!(info->dqi_flags & OLQF_CLEAN)) {
...@@ -759,7 +759,7 @@ static int ocfs2_local_write_info(struct super_block *sb, int type) ...@@ -759,7 +759,7 @@ static int ocfs2_local_write_info(struct super_block *sb, int type)
{ {
struct mem_dqinfo *info = sb_dqinfo(sb, type); struct mem_dqinfo *info = sb_dqinfo(sb, type);
struct buffer_head *bh = ((struct ocfs2_mem_dqinfo *)info->dqi_priv) struct buffer_head *bh = ((struct ocfs2_mem_dqinfo *)info->dqi_priv)
->dqi_ibh; ->dqi_libh;
int status; int status;
status = ocfs2_modify_bh(sb_dqopt(sb)->files[type], bh, olq_update_info, status = ocfs2_modify_bh(sb_dqopt(sb)->files[type], bh, olq_update_info,
...@@ -820,7 +820,7 @@ static int ocfs2_local_free_info(struct super_block *sb, int type) ...@@ -820,7 +820,7 @@ static int ocfs2_local_free_info(struct super_block *sb, int type)
/* Mark local file as clean */ /* Mark local file as clean */
info->dqi_flags |= OLQF_CLEAN; info->dqi_flags |= OLQF_CLEAN;
status = ocfs2_modify_bh(sb_dqopt(sb)->files[type], status = ocfs2_modify_bh(sb_dqopt(sb)->files[type],
oinfo->dqi_ibh, oinfo->dqi_libh,
olq_update_info, olq_update_info,
info); info);
if (status < 0) { if (status < 0) {
...@@ -830,7 +830,7 @@ static int ocfs2_local_free_info(struct super_block *sb, int type) ...@@ -830,7 +830,7 @@ static int ocfs2_local_free_info(struct super_block *sb, int type)
out: out:
ocfs2_inode_unlock(sb_dqopt(sb)->files[type], 1); ocfs2_inode_unlock(sb_dqopt(sb)->files[type], 1);
brelse(oinfo->dqi_ibh); brelse(oinfo->dqi_libh);
brelse(oinfo->dqi_lqi_bh); brelse(oinfo->dqi_lqi_bh);
kfree(oinfo); kfree(oinfo);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment