forked from pool/ocfs2-tools
c8700c5230
OBS-URL: https://build.opensuse.org/package/show/network:ha-clustering:Factory/ocfs2-tools?expand=0&rev=8
104 lines
3.1 KiB
Diff
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
|
|
|