diff options
-rw-r--r-- | fs/ocfs2/quota.h | 3 | ||||
-rw-r--r-- | fs/ocfs2/quota_global.c | 14 | ||||
-rw-r--r-- | fs/ocfs2/quota_local.c | 28 |
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 @@ | |||
23 | struct ocfs2_dquot { | 23 | struct 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); | |||
104 | void ocfs2_unlock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex); | 105 | void ocfs2_unlock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex); |
105 | int ocfs2_read_quota_block(struct inode *inode, u64 v_block, | 106 | int ocfs2_read_quota_block(struct inode *inode, u64 v_block, |
106 | struct buffer_head **bh); | 107 | struct buffer_head **bh); |
108 | int ocfs2_read_quota_phys_block(struct inode *inode, u64 p_block, | ||
109 | struct buffer_head **bh); | ||
107 | 110 | ||
108 | extern const struct dquot_operations ocfs2_quota_operations; | 111 | extern const struct dquot_operations ocfs2_quota_operations; |
109 | extern struct quota_format_type ocfs2_quota_format; | 112 | extern 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 | ||
30 | static struct workqueue_struct *ocfs2_quota_wq = NULL; | 31 | static 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 | ||
141 | int 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 | |||
140 | static int ocfs2_get_quota_block(struct inode *inode, int block, | 154 | static 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 | } |
1226 | out: | 1235 | out: |
1236 | up_write(&OCFS2_I(lqinode)->ip_alloc_sem); | ||
1227 | return status; | 1237 | return status; |
1228 | } | 1238 | } |
1229 | 1239 | ||