ocfs2-tools/0027-dx_dirs-stop-iteration-of-dir-trailer-initialization.patch

104 lines
3.1 KiB
Diff

From cb9471a5f73c69858d9dd35ea90b86476e65e4ca Mon Sep 17 00:00:00 2001
From: Coly Li <coly.li@suse.de>
Date: Mon, 26 Apr 2010 22:37:05 +0800
Subject: [PATCH 27/30] dx_dirs: stop iteration of dir trailer initialization for I/O error
Callback dir_trailer_func() may encounter malloc or I/O error, these
errors can not return to its caller directly. This patch add a member
'errcode_t err' to struct trailer_ctxt, which can catch the error. By
this fix, dir_trailer_func() can return OCFS2_EXTENT_ERROR to stop dir
iteration immediately and can return the REAL error as well.
Thanks to Tao Ma catches this error.
Signed-off-by: Coly Li <coly.li@suse.de>
Cc: Mark Fasheh <mfasheh@suse.com>
Cc: Tao Ma <tao.ma@oracle.com>
---
libocfs2/dir_indexed.c | 37 +++++++++++++++++++++++++++++--------
1 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/libocfs2/dir_indexed.c b/libocfs2/dir_indexed.c
index 9cae3d0..5f3db95 100644
--- a/libocfs2/dir_indexed.c
+++ b/libocfs2/dir_indexed.c
@@ -121,6 +121,7 @@ int ocfs2_find_max_rec_len(ocfs2_filesys *fs, char *buf)
struct trailer_ctxt {
struct ocfs2_dx_root_block *dx_root;
struct ocfs2_dinode *di;
+ errcode_t err;
};
/* make sure the space for trailer is reserved */
@@ -170,8 +171,8 @@ static int dir_trailer_func(ocfs2_filesys *fs,
struct ocfs2_dinode *di = ctxt->di;
struct ocfs2_dx_root_block *dx_root = ctxt->dx_root;
struct ocfs2_dir_block_trailer *trailer;
- int max_rec_len = 0;
- errcode_t ret = 0;
+ int max_rec_len = 0, ret = 0;
+ errcode_t err;
char *blk = NULL;
ret = ocfs2_malloc_block(fs->fs_io, &blk);
@@ -180,12 +181,20 @@ static int dir_trailer_func(ocfs2_filesys *fs,
/* here we don't trust trailer, cannot use
* ocfs2_read_dir_block() */
- ret = ocfs2_read_blocks(fs, blkno, 1, blk);
- if (ret)
+ err = ocfs2_read_blocks(fs, blkno, 1, blk);
+ if (err) {
+ ctxt->err = err;
+ ret = OCFS2_EXTENT_ERROR;
goto out;
- ret = ocfs2_check_dir_trailer_space(fs, di, blkno, blk);
- if (ret)
+ }
+
+ err = ocfs2_check_dir_trailer_space(fs, di, blkno, blk);
+ if (err) {
+ ctxt->err = err;
+ ret = OCFS2_EXTENT_ERROR;
goto out;
+ }
+
ocfs2_init_dir_trailer(fs, di, blkno, blk);
max_rec_len = ocfs2_find_max_rec_len(fs, blk);
trailer = ocfs2_dir_trailer_from_block(fs, blk);
@@ -198,7 +207,12 @@ static int dir_trailer_func(ocfs2_filesys *fs,
/* comput trailer->db_check here, after writes out,
* trailer is trustable */
- ret = ocfs2_write_dir_block(fs, di, blkno, blk);
+ err = ocfs2_write_dir_block(fs, di, blkno, blk);
+ if (err) {
+ ctxt->err = err;
+ ret = OCFS2_EXTENT_ERROR;
+ }
+
out:
if (blk)
ocfs2_free(&blk);
@@ -219,9 +233,16 @@ static errcode_t ocfs2_init_dir_trailers(ocfs2_filesys *fs,
ctxt.di = di;
ctxt.dx_root = dx_root;
-
+ ctxt.err = 0;
ret = ocfs2_block_iterate_inode(fs, di,
0, dir_trailer_func, &ctxt);
+
+ /* callback dir_trailer_func() may have error which can not
+ * return to its caller directly. If dir_trailer_func() sets
+ * error in ctxt.err, we should take this REAL error other
+ * than the value returned by ocfs2_block_iterate_inode(). */
+ if (ctxt.err)
+ ret = ctxt.err;
out:
return ret;
}
--
1.7.0.2