diff options
author | Jan Kara <jack@suse.cz> | 2010-04-28 13:04:29 -0400 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2010-05-21 13:30:46 -0400 |
commit | ae4f6ef13417deaa49471c0e903914a3ef3be258 (patch) | |
tree | b8ba5499a8ad69678a232ece4d64d18447063054 /fs/ocfs2 | |
parent | f64dd44eb748438783b10b3f7a4968d2656a3c95 (diff) |
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: Joel Becker <Joel.Becker@oracle.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/dlmglue.c | 3 | ||||
-rw-r--r-- | fs/ocfs2/quota.h | 3 | ||||
-rw-r--r-- | fs/ocfs2/quota_global.c | 15 | ||||
-rw-r--r-- | fs/ocfs2/quota_local.c | 10 |
4 files changed, 24 insertions, 7 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 50c4ee805da4..39eb16ac5f98 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
@@ -3897,7 +3897,8 @@ static int ocfs2_refresh_qinfo(struct ocfs2_mem_dqinfo *oinfo) | |||
3897 | oinfo->dqi_gi.dqi_free_entry = | 3897 | oinfo->dqi_gi.dqi_free_entry = |
3898 | be32_to_cpu(lvb->lvb_free_entry); | 3898 | be32_to_cpu(lvb->lvb_free_entry); |
3899 | } else { | 3899 | } else { |
3900 | status = ocfs2_read_quota_block(oinfo->dqi_gqinode, 0, &bh); | 3900 | status = ocfs2_read_quota_phys_block(oinfo->dqi_gqinode, |
3901 | oinfo->dqi_giblk, &bh); | ||
3901 | if (status) { | 3902 | if (status) { |
3902 | mlog_errno(status); | 3903 | mlog_errno(status); |
3903 | goto bail; | 3904 | goto bail; |
diff --git a/fs/ocfs2/quota.h b/fs/ocfs2/quota.h index e22d2935128e..c7623430ca3c 100644 --- a/fs/ocfs2/quota.h +++ b/fs/ocfs2/quota.h | |||
@@ -52,8 +52,9 @@ struct ocfs2_mem_dqinfo { | |||
52 | struct ocfs2_lock_res dqi_gqlock; /* Lock protecting quota information structure */ | 52 | struct ocfs2_lock_res dqi_gqlock; /* Lock protecting quota information structure */ |
53 | struct buffer_head *dqi_gqi_bh; /* Buffer head with global quota file inode - set only if inode lock is obtained */ | 53 | struct buffer_head *dqi_gqi_bh; /* Buffer head with global quota file inode - set only if inode lock is obtained */ |
54 | int dqi_gqi_count; /* Number of holders of dqi_gqi_bh */ | 54 | int dqi_gqi_count; /* Number of holders of dqi_gqi_bh */ |
55 | u64 dqi_giblk; /* Number of block with global information header */ | ||
55 | struct buffer_head *dqi_lqi_bh; /* Buffer head with local quota file inode */ | 56 | struct buffer_head *dqi_lqi_bh; /* Buffer head with local quota file inode */ |
56 | struct buffer_head *dqi_ibh; /* Buffer with information header */ | 57 | struct buffer_head *dqi_libh; /* Buffer with local information header */ |
57 | struct qtree_mem_dqinfo dqi_gi; /* Info about global file */ | 58 | struct qtree_mem_dqinfo dqi_gi; /* Info about global file */ |
58 | struct delayed_work dqi_sync_work; /* Work for syncing dquots */ | 59 | struct delayed_work dqi_sync_work; /* Work for syncing dquots */ |
59 | struct ocfs2_quota_recovery *dqi_rec; /* Pointer to recovery | 60 | struct ocfs2_quota_recovery *dqi_rec; /* Pointer to recovery |
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index f461f9678f9f..f391b11ea98c 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c | |||
@@ -325,6 +325,7 @@ int ocfs2_global_read_info(struct super_block *sb, int type) | |||
325 | struct ocfs2_global_disk_dqinfo dinfo; | 325 | struct ocfs2_global_disk_dqinfo dinfo; |
326 | struct mem_dqinfo *info = sb_dqinfo(sb, type); | 326 | struct mem_dqinfo *info = sb_dqinfo(sb, type); |
327 | struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv; | 327 | struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv; |
328 | u64 pcount; | ||
328 | int status; | 329 | int status; |
329 | 330 | ||
330 | mlog_entry_void(); | 331 | mlog_entry_void(); |
@@ -351,9 +352,19 @@ int ocfs2_global_read_info(struct super_block *sb, int type) | |||
351 | mlog_errno(status); | 352 | mlog_errno(status); |
352 | goto out_err; | 353 | goto out_err; |
353 | } | 354 | } |
355 | |||
356 | status = ocfs2_extent_map_get_blocks(gqinode, 0, &oinfo->dqi_giblk, | ||
357 | &pcount, NULL); | ||
358 | if (status < 0) | ||
359 | goto out_unlock; | ||
360 | |||
361 | status = ocfs2_qinfo_lock(oinfo, 0); | ||
362 | if (status < 0) | ||
363 | goto out_unlock; | ||
354 | status = sb->s_op->quota_read(sb, type, (char *)&dinfo, | 364 | status = sb->s_op->quota_read(sb, type, (char *)&dinfo, |
355 | sizeof(struct ocfs2_global_disk_dqinfo), | 365 | sizeof(struct ocfs2_global_disk_dqinfo), |
356 | OCFS2_GLOBAL_INFO_OFF); | 366 | OCFS2_GLOBAL_INFO_OFF); |
367 | ocfs2_qinfo_unlock(oinfo, 0); | ||
357 | ocfs2_unlock_global_qf(oinfo, 0); | 368 | ocfs2_unlock_global_qf(oinfo, 0); |
358 | if (status != sizeof(struct ocfs2_global_disk_dqinfo)) { | 369 | if (status != sizeof(struct ocfs2_global_disk_dqinfo)) { |
359 | mlog(ML_ERROR, "Cannot read global quota info (%d).\n", | 370 | 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 | out_err: | 391 | out_err: |
381 | mlog_exit(status); | 392 | mlog_exit(status); |
382 | return status; | 393 | return status; |
394 | out_unlock: | ||
395 | ocfs2_unlock_global_qf(oinfo, 0); | ||
396 | mlog_errno(status); | ||
397 | goto out_err; | ||
383 | } | 398 | } |
384 | 399 | ||
385 | /* Write information to global quota file. Expects exlusive lock on quota | 400 | /* Write information to global quota file. Expects exlusive lock on quota |
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c index a88f1d1ec2b4..962e8380852b 100644 --- a/fs/ocfs2/quota_local.c +++ b/fs/ocfs2/quota_local.c | |||
@@ -671,7 +671,7 @@ static int ocfs2_local_read_info(struct super_block *sb, int type) | |||
671 | INIT_LIST_HEAD(&oinfo->dqi_chunk); | 671 | INIT_LIST_HEAD(&oinfo->dqi_chunk); |
672 | oinfo->dqi_rec = NULL; | 672 | oinfo->dqi_rec = NULL; |
673 | oinfo->dqi_lqi_bh = NULL; | 673 | oinfo->dqi_lqi_bh = NULL; |
674 | oinfo->dqi_ibh = NULL; | 674 | oinfo->dqi_libh = NULL; |
675 | 675 | ||
676 | status = ocfs2_global_read_info(sb, type); | 676 | status = ocfs2_global_read_info(sb, type); |
677 | if (status < 0) | 677 | if (status < 0) |
@@ -697,7 +697,7 @@ static int ocfs2_local_read_info(struct super_block *sb, int type) | |||
697 | info->dqi_flags = le32_to_cpu(ldinfo->dqi_flags); | 697 | info->dqi_flags = le32_to_cpu(ldinfo->dqi_flags); |
698 | oinfo->dqi_chunks = le32_to_cpu(ldinfo->dqi_chunks); | 698 | oinfo->dqi_chunks = le32_to_cpu(ldinfo->dqi_chunks); |
699 | oinfo->dqi_blocks = le32_to_cpu(ldinfo->dqi_blocks); | 699 | oinfo->dqi_blocks = le32_to_cpu(ldinfo->dqi_blocks); |
700 | oinfo->dqi_ibh = bh; | 700 | oinfo->dqi_libh = bh; |
701 | 701 | ||
702 | /* We crashed when using local quota file? */ | 702 | /* We crashed when using local quota file? */ |
703 | if (!(info->dqi_flags & OLQF_CLEAN)) { | 703 | if (!(info->dqi_flags & OLQF_CLEAN)) { |
@@ -759,7 +759,7 @@ static int ocfs2_local_write_info(struct super_block *sb, int type) | |||
759 | { | 759 | { |
760 | struct mem_dqinfo *info = sb_dqinfo(sb, type); | 760 | struct mem_dqinfo *info = sb_dqinfo(sb, type); |
761 | struct buffer_head *bh = ((struct ocfs2_mem_dqinfo *)info->dqi_priv) | 761 | struct buffer_head *bh = ((struct ocfs2_mem_dqinfo *)info->dqi_priv) |
762 | ->dqi_ibh; | 762 | ->dqi_libh; |
763 | int status; | 763 | int status; |
764 | 764 | ||
765 | status = ocfs2_modify_bh(sb_dqopt(sb)->files[type], bh, olq_update_info, | 765 | 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 | /* Mark local file as clean */ | 820 | /* Mark local file as clean */ |
821 | info->dqi_flags |= OLQF_CLEAN; | 821 | info->dqi_flags |= OLQF_CLEAN; |
822 | status = ocfs2_modify_bh(sb_dqopt(sb)->files[type], | 822 | status = ocfs2_modify_bh(sb_dqopt(sb)->files[type], |
823 | oinfo->dqi_ibh, | 823 | oinfo->dqi_libh, |
824 | olq_update_info, | 824 | olq_update_info, |
825 | info); | 825 | info); |
826 | if (status < 0) { | 826 | if (status < 0) { |
@@ -830,7 +830,7 @@ static int ocfs2_local_free_info(struct super_block *sb, int type) | |||
830 | 830 | ||
831 | out: | 831 | out: |
832 | ocfs2_inode_unlock(sb_dqopt(sb)->files[type], 1); | 832 | ocfs2_inode_unlock(sb_dqopt(sb)->files[type], 1); |
833 | brelse(oinfo->dqi_ibh); | 833 | brelse(oinfo->dqi_libh); |
834 | brelse(oinfo->dqi_lqi_bh); | 834 | brelse(oinfo->dqi_lqi_bh); |
835 | kfree(oinfo); | 835 | kfree(oinfo); |
836 | return 0; | 836 | return 0; |