aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Becker <Joel.Becker@oracle.com>2008-11-25 09:31:27 -0500
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:40:24 -0500
commit85eb8b73d66530bb7b931789ae7a5ec9744eed34 (patch)
tree4590be147364e0437f23a0d6bf72ccc900852eb9
parent57a09a7b3d9445a17c78d544f1e49d4d7d61705a (diff)
ocfs2: Fix ocfs2_read_quota_block() error handling.
ocfs2_bread() has become ocfs2_read_virt_blocks(), with a prototype to match ocfs2_read_blocks(). The quota code, converting from ocfs2_bread(), wraps the call to ocfs2_read_virt_blocks() in ocfs2_read_quota_block(). Unfortunately, the prototype of ocfs2_read_quota_block() matches the old prototype of ocfs2_bread(). The problem is that ocfs2_bread() returned the buffer head, and callers assumed that a NULL pointer was indicative of error. It wasn't. This is why ocfs2_bread() took an int*err argument as well. The new prototype of ocfs2_read_virt_blocks() avoids this error handling confusion. Let's change ocfs2_read_quota_block() to match. Signed-off-by: Joel Becker <joel.becker@oracle.com> Acked-by: Jan Kara <jack@suse.cz> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
-rw-r--r--fs/ocfs2/dlmglue.c6
-rw-r--r--fs/ocfs2/quota.h4
-rw-r--r--fs/ocfs2/quota_global.c34
-rw-r--r--fs/ocfs2/quota_local.c64
4 files changed, 60 insertions, 48 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 058aa86490a..b1c75911d8a 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -3519,7 +3519,7 @@ static int ocfs2_refresh_qinfo(struct ocfs2_mem_dqinfo *oinfo)
3519 oinfo->dqi_gi.dqi_type); 3519 oinfo->dqi_gi.dqi_type);
3520 struct ocfs2_lock_res *lockres = &oinfo->dqi_gqlock; 3520 struct ocfs2_lock_res *lockres = &oinfo->dqi_gqlock;
3521 struct ocfs2_qinfo_lvb *lvb = ocfs2_dlm_lvb(&lockres->l_lksb); 3521 struct ocfs2_qinfo_lvb *lvb = ocfs2_dlm_lvb(&lockres->l_lksb);
3522 struct buffer_head *bh; 3522 struct buffer_head *bh = NULL;
3523 struct ocfs2_global_disk_dqinfo *gdinfo; 3523 struct ocfs2_global_disk_dqinfo *gdinfo;
3524 int status = 0; 3524 int status = 0;
3525 3525
@@ -3532,8 +3532,8 @@ static int ocfs2_refresh_qinfo(struct ocfs2_mem_dqinfo *oinfo)
3532 oinfo->dqi_gi.dqi_free_entry = 3532 oinfo->dqi_gi.dqi_free_entry =
3533 be32_to_cpu(lvb->lvb_free_entry); 3533 be32_to_cpu(lvb->lvb_free_entry);
3534 } else { 3534 } else {
3535 bh = ocfs2_read_quota_block(oinfo->dqi_gqinode, 0, &status); 3535 status = ocfs2_read_quota_block(oinfo->dqi_gqinode, 0, &bh);
3536 if (!bh) { 3536 if (status) {
3537 mlog_errno(status); 3537 mlog_errno(status);
3538 goto bail; 3538 goto bail;
3539 } 3539 }
diff --git a/fs/ocfs2/quota.h b/fs/ocfs2/quota.h
index 04872b45b99..7365e2e0870 100644
--- a/fs/ocfs2/quota.h
+++ b/fs/ocfs2/quota.h
@@ -107,8 +107,8 @@ static inline int ocfs2_global_release_dquot(struct dquot *dquot)
107 107
108int ocfs2_lock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex); 108int ocfs2_lock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex);
109void ocfs2_unlock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex); 109void ocfs2_unlock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex);
110struct buffer_head *ocfs2_read_quota_block(struct inode *inode, 110int ocfs2_read_quota_block(struct inode *inode, u64 v_block,
111 int block, int *err); 111 struct buffer_head **bh);
112 112
113extern struct dquot_operations ocfs2_quota_operations; 113extern struct dquot_operations ocfs2_quota_operations;
114extern struct quota_format_type ocfs2_quota_format; 114extern struct quota_format_type ocfs2_quota_format;
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c
index 10ecb33298d..2bdcddd3f1c 100644
--- a/fs/ocfs2/quota_global.c
+++ b/fs/ocfs2/quota_global.c
@@ -87,16 +87,21 @@ struct qtree_fmt_operations ocfs2_global_ops = {
87 .is_id = ocfs2_global_is_id, 87 .is_id = ocfs2_global_is_id,
88}; 88};
89 89
90struct buffer_head *ocfs2_read_quota_block(struct inode *inode, 90int ocfs2_read_quota_block(struct inode *inode, u64 v_block,
91 int block, int *err) 91 struct buffer_head **bh)
92{ 92{
93 struct buffer_head *tmp = NULL; 93 int rc = 0;
94 struct buffer_head *tmp = *bh;
94 95
95 *err = ocfs2_read_virt_blocks(inode, block, 1, &tmp, 0, NULL); 96 rc = ocfs2_read_virt_blocks(inode, v_block, 1, &tmp, 0, NULL);
96 if (*err) 97 if (rc)
97 mlog_errno(*err); 98 mlog_errno(rc);
99
100 /* If ocfs2_read_virt_blocks() got us a new bh, pass it up. */
101 if (!rc && !*bh)
102 *bh = tmp;
98 103
99 return tmp; 104 return rc;
100} 105}
101 106
102static struct buffer_head *ocfs2_get_quota_block(struct inode *inode, 107static struct buffer_head *ocfs2_get_quota_block(struct inode *inode,
@@ -143,8 +148,9 @@ ssize_t ocfs2_quota_read(struct super_block *sb, int type, char *data,
143 toread = len; 148 toread = len;
144 while (toread > 0) { 149 while (toread > 0) {
145 tocopy = min((size_t)(sb->s_blocksize - offset), toread); 150 tocopy = min((size_t)(sb->s_blocksize - offset), toread);
146 bh = ocfs2_read_quota_block(gqinode, blk, &err); 151 bh = NULL;
147 if (!bh) { 152 err = ocfs2_read_quota_block(gqinode, blk, &bh);
153 if (err) {
148 mlog_errno(err); 154 mlog_errno(err);
149 return err; 155 return err;
150 } 156 }
@@ -169,7 +175,7 @@ ssize_t ocfs2_quota_write(struct super_block *sb, int type,
169 int offset = off & (sb->s_blocksize - 1); 175 int offset = off & (sb->s_blocksize - 1);
170 sector_t blk = off >> sb->s_blocksize_bits; 176 sector_t blk = off >> sb->s_blocksize_bits;
171 int err = 0, new = 0; 177 int err = 0, new = 0;
172 struct buffer_head *bh; 178 struct buffer_head *bh = NULL;
173 handle_t *handle = journal_current_handle(); 179 handle_t *handle = journal_current_handle();
174 180
175 if (!handle) { 181 if (!handle) {
@@ -200,13 +206,13 @@ ssize_t ocfs2_quota_write(struct super_block *sb, int type,
200 /* Not rewriting whole block? */ 206 /* Not rewriting whole block? */
201 if ((offset || len < sb->s_blocksize - OCFS2_QBLK_RESERVED_SPACE) && 207 if ((offset || len < sb->s_blocksize - OCFS2_QBLK_RESERVED_SPACE) &&
202 !new) { 208 !new) {
203 bh = ocfs2_read_quota_block(gqinode, blk, &err); 209 err = ocfs2_read_quota_block(gqinode, blk, &bh);
204 if (!bh) { 210 if (err) {
205 mlog_errno(err); 211 mlog_errno(err);
206 return err; 212 return err;
207 } 213 }
208 err = ocfs2_journal_access(handle, gqinode, bh, 214 err = ocfs2_journal_access(handle, gqinode, bh,
209 OCFS2_JOURNAL_ACCESS_WRITE); 215 OCFS2_JOURNAL_ACCESS_WRITE);
210 } else { 216 } else {
211 bh = ocfs2_get_quota_block(gqinode, blk, &err); 217 bh = ocfs2_get_quota_block(gqinode, blk, &err);
212 if (!bh) { 218 if (!bh) {
@@ -214,7 +220,7 @@ ssize_t ocfs2_quota_write(struct super_block *sb, int type,
214 return err; 220 return err;
215 } 221 }
216 err = ocfs2_journal_access(handle, gqinode, bh, 222 err = ocfs2_journal_access(handle, gqinode, bh,
217 OCFS2_JOURNAL_ACCESS_CREATE); 223 OCFS2_JOURNAL_ACCESS_CREATE);
218 } 224 }
219 if (err < 0) { 225 if (err < 0) {
220 brelse(bh); 226 brelse(bh);
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c
index b98562174cd..7053664f66a 100644
--- a/fs/ocfs2/quota_local.c
+++ b/fs/ocfs2/quota_local.c
@@ -139,15 +139,15 @@ static int ocfs2_local_check_quota_file(struct super_block *sb, int type)
139 unsigned int gversions[MAXQUOTAS] = OCFS2_GLOBAL_QVERSIONS; 139 unsigned int gversions[MAXQUOTAS] = OCFS2_GLOBAL_QVERSIONS;
140 unsigned int ino[MAXQUOTAS] = { USER_QUOTA_SYSTEM_INODE, 140 unsigned int ino[MAXQUOTAS] = { USER_QUOTA_SYSTEM_INODE,
141 GROUP_QUOTA_SYSTEM_INODE }; 141 GROUP_QUOTA_SYSTEM_INODE };
142 struct buffer_head *bh; 142 struct buffer_head *bh = NULL;
143 struct inode *linode = sb_dqopt(sb)->files[type]; 143 struct inode *linode = sb_dqopt(sb)->files[type];
144 struct inode *ginode = NULL; 144 struct inode *ginode = NULL;
145 struct ocfs2_disk_dqheader *dqhead; 145 struct ocfs2_disk_dqheader *dqhead;
146 int status, ret = 0; 146 int status, ret = 0;
147 147
148 /* First check whether we understand local quota file */ 148 /* First check whether we understand local quota file */
149 bh = ocfs2_read_quota_block(linode, 0, &status); 149 status = ocfs2_read_quota_block(linode, 0, &bh);
150 if (!bh) { 150 if (status) {
151 mlog_errno(status); 151 mlog_errno(status);
152 mlog(ML_ERROR, "failed to read quota file header (type=%d)\n", 152 mlog(ML_ERROR, "failed to read quota file header (type=%d)\n",
153 type); 153 type);
@@ -178,8 +178,8 @@ static int ocfs2_local_check_quota_file(struct super_block *sb, int type)
178 goto out_err; 178 goto out_err;
179 } 179 }
180 /* Since the header is read only, we don't care about locking */ 180 /* Since the header is read only, we don't care about locking */
181 bh = ocfs2_read_quota_block(ginode, 0, &status); 181 status = ocfs2_read_quota_block(ginode, 0, &bh);
182 if (!bh) { 182 if (status) {
183 mlog_errno(status); 183 mlog_errno(status);
184 mlog(ML_ERROR, "failed to read global quota file header " 184 mlog(ML_ERROR, "failed to read global quota file header "
185 "(type=%d)\n", type); 185 "(type=%d)\n", type);
@@ -235,10 +235,11 @@ static int ocfs2_load_local_quota_bitmaps(struct inode *inode,
235 return -ENOMEM; 235 return -ENOMEM;
236 } 236 }
237 newchunk->qc_num = i; 237 newchunk->qc_num = i;
238 newchunk->qc_headerbh = ocfs2_read_quota_block(inode, 238 newchunk->qc_headerbh = NULL;
239 status = ocfs2_read_quota_block(inode,
239 ol_quota_chunk_block(inode->i_sb, i), 240 ol_quota_chunk_block(inode->i_sb, i),
240 &status); 241 &newchunk->qc_headerbh);
241 if (!newchunk->qc_headerbh) { 242 if (status) {
242 mlog_errno(status); 243 mlog_errno(status);
243 kmem_cache_free(ocfs2_qf_chunk_cachep, newchunk); 244 kmem_cache_free(ocfs2_qf_chunk_cachep, newchunk);
244 ocfs2_release_local_quota_bitmaps(head); 245 ocfs2_release_local_quota_bitmaps(head);
@@ -320,10 +321,11 @@ static int ocfs2_recovery_load_quota(struct inode *lqinode,
320 int status = 0; 321 int status = 0;
321 322
322 for (i = 0; i < chunks; i++) { 323 for (i = 0; i < chunks; i++) {
323 hbh = ocfs2_read_quota_block(lqinode, 324 hbh = NULL;
324 ol_quota_chunk_block(sb, i), 325 status = ocfs2_read_quota_block(lqinode,
325 &status); 326 ol_quota_chunk_block(sb, i),
326 if (!hbh) { 327 &hbh);
328 if (status) {
327 mlog_errno(status); 329 mlog_errno(status);
328 break; 330 break;
329 } 331 }
@@ -392,8 +394,9 @@ struct ocfs2_quota_recovery *ocfs2_begin_quota_recovery(
392 goto out_put; 394 goto out_put;
393 } 395 }
394 /* Now read local header */ 396 /* Now read local header */
395 bh = ocfs2_read_quota_block(lqinode, 0, &status); 397 bh = NULL;
396 if (!bh) { 398 status = ocfs2_read_quota_block(lqinode, 0, &bh);
399 if (status) {
397 mlog_errno(status); 400 mlog_errno(status);
398 mlog(ML_ERROR, "failed to read quota file info header " 401 mlog(ML_ERROR, "failed to read quota file info header "
399 "(slot=%d type=%d)\n", slot_num, type); 402 "(slot=%d type=%d)\n", slot_num, type);
@@ -447,19 +450,21 @@ static int ocfs2_recover_local_quota_file(struct inode *lqinode,
447 450
448 list_for_each_entry_safe(rchunk, next, &(rec->r_list[type]), rc_list) { 451 list_for_each_entry_safe(rchunk, next, &(rec->r_list[type]), rc_list) {
449 chunk = rchunk->rc_chunk; 452 chunk = rchunk->rc_chunk;
450 hbh = ocfs2_read_quota_block(lqinode, 453 hbh = NULL;
451 ol_quota_chunk_block(sb, chunk), 454 status = ocfs2_read_quota_block(lqinode,
452 &status); 455 ol_quota_chunk_block(sb, chunk),
453 if (!hbh) { 456 &hbh);
457 if (status) {
454 mlog_errno(status); 458 mlog_errno(status);
455 break; 459 break;
456 } 460 }
457 dchunk = (struct ocfs2_local_disk_chunk *)hbh->b_data; 461 dchunk = (struct ocfs2_local_disk_chunk *)hbh->b_data;
458 for_each_bit(bit, rchunk->rc_bitmap, ol_chunk_entries(sb)) { 462 for_each_bit(bit, rchunk->rc_bitmap, ol_chunk_entries(sb)) {
459 qbh = ocfs2_read_quota_block(lqinode, 463 qbh = NULL;
464 status = ocfs2_read_quota_block(lqinode,
460 ol_dqblk_block(sb, chunk, bit), 465 ol_dqblk_block(sb, chunk, bit),
461 &status); 466 &qbh);
462 if (!qbh) { 467 if (status) {
463 mlog_errno(status); 468 mlog_errno(status);
464 break; 469 break;
465 } 470 }
@@ -581,8 +586,9 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
581 goto out_put; 586 goto out_put;
582 } 587 }
583 /* Now read local header */ 588 /* Now read local header */
584 bh = ocfs2_read_quota_block(lqinode, 0, &status); 589 bh = NULL;
585 if (!bh) { 590 status = ocfs2_read_quota_block(lqinode, 0, &bh);
591 if (status) {
586 mlog_errno(status); 592 mlog_errno(status);
587 mlog(ML_ERROR, "failed to read quota file info header " 593 mlog(ML_ERROR, "failed to read quota file info header "
588 "(slot=%d type=%d)\n", slot_num, type); 594 "(slot=%d type=%d)\n", slot_num, type);
@@ -676,8 +682,8 @@ static int ocfs2_local_read_info(struct super_block *sb, int type)
676 locked = 1; 682 locked = 1;
677 683
678 /* Now read local header */ 684 /* Now read local header */
679 bh = ocfs2_read_quota_block(lqinode, 0, &status); 685 status = ocfs2_read_quota_block(lqinode, 0, &bh);
680 if (!bh) { 686 if (status) {
681 mlog_errno(status); 687 mlog_errno(status);
682 mlog(ML_ERROR, "failed to read quota file info header " 688 mlog(ML_ERROR, "failed to read quota file info header "
683 "(type=%d)\n", type); 689 "(type=%d)\n", type);
@@ -850,13 +856,13 @@ static int ocfs2_local_write_dquot(struct dquot *dquot)
850{ 856{
851 struct super_block *sb = dquot->dq_sb; 857 struct super_block *sb = dquot->dq_sb;
852 struct ocfs2_dquot *od = OCFS2_DQUOT(dquot); 858 struct ocfs2_dquot *od = OCFS2_DQUOT(dquot);
853 struct buffer_head *bh; 859 struct buffer_head *bh = NULL;
854 int status; 860 int status;
855 861
856 bh = ocfs2_read_quota_block(sb_dqopt(sb)->files[dquot->dq_type], 862 status = ocfs2_read_quota_block(sb_dqopt(sb)->files[dquot->dq_type],
857 ol_dqblk_file_block(sb, od->dq_local_off), 863 ol_dqblk_file_block(sb, od->dq_local_off),
858 &status); 864 &bh);
859 if (!bh) { 865 if (status) {
860 mlog_errno(status); 866 mlog_errno(status);
861 goto out; 867 goto out;
862 } 868 }