aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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