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

Commit ae4f6ef1 authored by Jan Kara's avatar Jan Kara
Browse files

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
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -3897,7 +3897,8 @@ static int ocfs2_refresh_qinfo(struct ocfs2_mem_dqinfo *oinfo)
		oinfo->dqi_gi.dqi_free_entry =
					be32_to_cpu(lvb->lvb_free_entry);
	} 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) {
			mlog_errno(status);
			goto bail;
+2 −1
Original line number Diff line number Diff line
@@ -52,8 +52,9 @@ struct ocfs2_mem_dqinfo {
	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 */
	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_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 delayed_work dqi_sync_work;	/* Work for syncing dquots */
	struct ocfs2_quota_recovery *dqi_rec;	/* Pointer to recovery
+15 −0
Original line number Diff line number Diff line
@@ -325,6 +325,7 @@ int ocfs2_global_read_info(struct super_block *sb, int type)
	struct ocfs2_global_disk_dqinfo dinfo;
	struct mem_dqinfo *info = sb_dqinfo(sb, type);
	struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
	u64 pcount;
	int status;

	mlog_entry_void();
@@ -351,9 +352,19 @@ int ocfs2_global_read_info(struct super_block *sb, int type)
		mlog_errno(status);
		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,
				      sizeof(struct ocfs2_global_disk_dqinfo),
				      OCFS2_GLOBAL_INFO_OFF);
	ocfs2_qinfo_unlock(oinfo, 0);
	ocfs2_unlock_global_qf(oinfo, 0);
	if (status != sizeof(struct ocfs2_global_disk_dqinfo)) {
		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)
out_err:
	mlog_exit(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
+5 −5
Original line number Diff line number Diff line
@@ -671,7 +671,7 @@ static int ocfs2_local_read_info(struct super_block *sb, int type)
	INIT_LIST_HEAD(&oinfo->dqi_chunk);
	oinfo->dqi_rec = NULL;
	oinfo->dqi_lqi_bh = NULL;
	oinfo->dqi_ibh = NULL;
	oinfo->dqi_libh = NULL;

	status = ocfs2_global_read_info(sb, type);
	if (status < 0)
@@ -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);
	oinfo->dqi_chunks = le32_to_cpu(ldinfo->dqi_chunks);
	oinfo->dqi_blocks = le32_to_cpu(ldinfo->dqi_blocks);
	oinfo->dqi_ibh = bh;
	oinfo->dqi_libh = bh;

	/* We crashed when using local quota file? */
	if (!(info->dqi_flags & OLQF_CLEAN)) {
@@ -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 buffer_head *bh = ((struct ocfs2_mem_dqinfo *)info->dqi_priv)
						->dqi_ibh;
						->dqi_libh;
	int status;

	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)
	/* Mark local file as clean */
	info->dqi_flags |= OLQF_CLEAN;
	status = ocfs2_modify_bh(sb_dqopt(sb)->files[type],
				 oinfo->dqi_ibh,
				 oinfo->dqi_libh,
				 olq_update_info,
				 info);
	if (status < 0) {
@@ -830,7 +830,7 @@ static int ocfs2_local_free_info(struct super_block *sb, int type)

out:
	ocfs2_inode_unlock(sb_dqopt(sb)->files[type], 1);
	brelse(oinfo->dqi_ibh);
	brelse(oinfo->dqi_libh);
	brelse(oinfo->dqi_lqi_bh);
	kfree(oinfo);
	return 0;