aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2010-04-27 18:22:30 -0400
committerJan Kara <jack@suse.cz>2010-05-21 13:30:46 -0400
commitf64dd44eb748438783b10b3f7a4968d2656a3c95 (patch)
tree21d73e0ed7140c8a61331eacd65157cc0983a16d /fs/ocfs2
parentbc8e5f07392f05c47c8bdeff4f7098db440d065c (diff)
ocfs2: Do not map blocks from local quota file on each write
There is no need to map offset of local dquot structure to on disk block in each quota write. It is enough to map it just once and store the physical block number in quota structure in memory. Moreover this simplifies locking as we do not have to take ip_alloc_sem from quota write path. 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/quota.h3
-rw-r--r--fs/ocfs2/quota_global.c14
-rw-r--r--fs/ocfs2/quota_local.c28
3 files changed, 36 insertions, 9 deletions
diff --git a/fs/ocfs2/quota.h b/fs/ocfs2/quota.h
index 123bc520a2c0..e22d2935128e 100644
--- a/fs/ocfs2/quota.h
+++ b/fs/ocfs2/quota.h
@@ -23,6 +23,7 @@
23struct ocfs2_dquot { 23struct ocfs2_dquot {
24 struct dquot dq_dquot; /* Generic VFS dquot */ 24 struct dquot dq_dquot; /* Generic VFS dquot */
25 loff_t dq_local_off; /* Offset in the local quota file */ 25 loff_t dq_local_off; /* Offset in the local quota file */
26 u64 dq_local_phys_blk; /* Physical block carrying quota structure */
26 struct ocfs2_quota_chunk *dq_chunk; /* Chunk dquot is in */ 27 struct ocfs2_quota_chunk *dq_chunk; /* Chunk dquot is in */
27 unsigned int dq_use_count; /* Number of nodes having reference to this entry in global quota file */ 28 unsigned int dq_use_count; /* Number of nodes having reference to this entry in global quota file */
28 s64 dq_origspace; /* Last globally synced space usage */ 29 s64 dq_origspace; /* Last globally synced space usage */
@@ -104,6 +105,8 @@ int ocfs2_lock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex);
104void ocfs2_unlock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex); 105void ocfs2_unlock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex);
105int ocfs2_read_quota_block(struct inode *inode, u64 v_block, 106int ocfs2_read_quota_block(struct inode *inode, u64 v_block,
106 struct buffer_head **bh); 107 struct buffer_head **bh);
108int ocfs2_read_quota_phys_block(struct inode *inode, u64 p_block,
109 struct buffer_head **bh);
107 110
108extern const struct dquot_operations ocfs2_quota_operations; 111extern const struct dquot_operations ocfs2_quota_operations;
109extern struct quota_format_type ocfs2_quota_format; 112extern struct quota_format_type ocfs2_quota_format;
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c
index 04ae76d8c6ab..f461f9678f9f 100644
--- a/fs/ocfs2/quota_global.c
+++ b/fs/ocfs2/quota_global.c
@@ -25,6 +25,7 @@
25#include "dlmglue.h" 25#include "dlmglue.h"
26#include "uptodate.h" 26#include "uptodate.h"
27#include "super.h" 27#include "super.h"
28#include "buffer_head_io.h"
28#include "quota.h" 29#include "quota.h"
29 30
30static struct workqueue_struct *ocfs2_quota_wq = NULL; 31static struct workqueue_struct *ocfs2_quota_wq = NULL;
@@ -137,6 +138,19 @@ int ocfs2_read_quota_block(struct inode *inode, u64 v_block,
137 return rc; 138 return rc;
138} 139}
139 140
141int ocfs2_read_quota_phys_block(struct inode *inode, u64 p_block,
142 struct buffer_head **bhp)
143{
144 int rc;
145
146 *bhp = NULL;
147 rc = ocfs2_read_blocks(INODE_CACHE(inode), p_block, 1, bhp, 0,
148 ocfs2_validate_quota_block);
149 if (rc)
150 mlog_errno(rc);
151 return rc;
152}
153
140static int ocfs2_get_quota_block(struct inode *inode, int block, 154static int ocfs2_get_quota_block(struct inode *inode, int block,
141 struct buffer_head **bh) 155 struct buffer_head **bh)
142{ 156{
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c
index 884b641f199e..a88f1d1ec2b4 100644
--- a/fs/ocfs2/quota_local.c
+++ b/fs/ocfs2/quota_local.c
@@ -862,18 +862,17 @@ static int ocfs2_local_write_dquot(struct dquot *dquot)
862{ 862{
863 struct super_block *sb = dquot->dq_sb; 863 struct super_block *sb = dquot->dq_sb;
864 struct ocfs2_dquot *od = OCFS2_DQUOT(dquot); 864 struct ocfs2_dquot *od = OCFS2_DQUOT(dquot);
865 struct buffer_head *bh = NULL; 865 struct buffer_head *bh;
866 struct inode *lqinode = sb_dqopt(sb)->files[dquot->dq_type];
866 int status; 867 int status;
867 868
868 status = ocfs2_read_quota_block(sb_dqopt(sb)->files[dquot->dq_type], 869 status = ocfs2_read_quota_phys_block(lqinode, od->dq_local_phys_blk,
869 ol_dqblk_file_block(sb, od->dq_local_off), 870 &bh);
870 &bh);
871 if (status) { 871 if (status) {
872 mlog_errno(status); 872 mlog_errno(status);
873 goto out; 873 goto out;
874 } 874 }
875 status = ocfs2_modify_bh(sb_dqopt(sb)->files[dquot->dq_type], bh, 875 status = ocfs2_modify_bh(lqinode, bh, olq_set_dquot, od);
876 olq_set_dquot, od);
877 if (status < 0) { 876 if (status < 0) {
878 mlog_errno(status); 877 mlog_errno(status);
879 goto out; 878 goto out;
@@ -1197,17 +1196,27 @@ static int ocfs2_create_local_dquot(struct dquot *dquot)
1197 struct ocfs2_dquot *od = OCFS2_DQUOT(dquot); 1196 struct ocfs2_dquot *od = OCFS2_DQUOT(dquot);
1198 int offset; 1197 int offset;
1199 int status; 1198 int status;
1199 u64 pcount;
1200 1200
1201 down_write(&OCFS2_I(lqinode)->ip_alloc_sem);
1201 chunk = ocfs2_find_free_entry(sb, type, &offset); 1202 chunk = ocfs2_find_free_entry(sb, type, &offset);
1202 if (!chunk) { 1203 if (!chunk) {
1203 chunk = ocfs2_extend_local_quota_file(sb, type, &offset); 1204 chunk = ocfs2_extend_local_quota_file(sb, type, &offset);
1204 if (IS_ERR(chunk)) 1205 if (IS_ERR(chunk)) {
1205 return PTR_ERR(chunk); 1206 status = PTR_ERR(chunk);
1207 goto out;
1208 }
1206 } else if (IS_ERR(chunk)) { 1209 } else if (IS_ERR(chunk)) {
1207 return PTR_ERR(chunk); 1210 status = PTR_ERR(chunk);
1211 goto out;
1208 } 1212 }
1209 od->dq_local_off = ol_dqblk_off(sb, chunk->qc_num, offset); 1213 od->dq_local_off = ol_dqblk_off(sb, chunk->qc_num, offset);
1210 od->dq_chunk = chunk; 1214 od->dq_chunk = chunk;
1215 status = ocfs2_extent_map_get_blocks(lqinode,
1216 ol_dqblk_block(sb, chunk->qc_num, offset),
1217 &od->dq_local_phys_blk,
1218 &pcount,
1219 NULL);
1211 1220
1212 /* Initialize dquot structure on disk */ 1221 /* Initialize dquot structure on disk */
1213 status = ocfs2_local_write_dquot(dquot); 1222 status = ocfs2_local_write_dquot(dquot);
@@ -1224,6 +1233,7 @@ static int ocfs2_create_local_dquot(struct dquot *dquot)
1224 goto out; 1233 goto out;
1225 } 1234 }
1226out: 1235out:
1236 up_write(&OCFS2_I(lqinode)->ip_alloc_sem);
1227 return status; 1237 return status;
1228} 1238}
1229 1239